smiley-http-proxy-servlet 实现springboot 接口反向代理,站点代理,项目鉴权,安全的引入第三方项目服务

背景:
项目初期 和硬件集成,实现了些功能服务,由于是局域网环境,安全问题当时都可以最小化无视。随着对接的服务越来越多,部分功能上云,此时就需要有一种手段可以控制到其他项目/接口的访问权限。 无疑 反向代理是最轻快的解决办法。

反向代理 集成第三方的服务接口或web监控界面,并与项目实现的鉴权方法

依赖 smiley-http-proxy-servlet GitHub链接

  2.0 版开始,代理切换到jakarta servlet-api<!--HTTP 代理 Servlet--><dependency><groupId>org.mitre.dsmiley.httpproxy</groupId><artifactId>smiley-http-proxy-servlet</artifactId><version>2.0</version></dependency>

javax servlet-api 请选择


<dependency><groupId>org.mitre.dsmiley.httpproxy</groupId><artifactId>smiley-http-proxy-servlet</artifactId><version>${smiley-http-proxy-servlet.version}</version><classifier>javax</classifier>
</dependency>

仅仅是代理接口 默认官网示例使用即可,参考第二个接口代理。

以Nginx 代理Grafana监控平台为例,解决静态资源加载失败、访问鉴权、及websocket连接问题

import org.mitre.dsmiley.httpproxy.ProxyServlet;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.HiddenHttpMethodFilter;/*** 本地代理服务** @author Smile*/
@Configuration
public class ProxyServletConfig {/*** 代理Grafana 监控平台*/	@Beanpublic ServletRegistrationBean<ProxyServlet> servletRegistrationBean() {ServletRegistrationBean<ProxyServlet> servletRegistrationBean = new ServletRegistrationBean<>(new ProxyServlet(), "/grafana/*");servletRegistrationBean.addInitParameter(ProxyServlet.P_TARGET_URI, "http://127.0.0.1:9999");servletRegistrationBean.addInitParameter(ProxyServlet.P_LOG, "true");
//       自动处理重定向servletRegistrationBean.addInitParameter(ProxyServlet.P_HANDLEREDIRECTS, "false");
//      保持 COOKIES 不变servletRegistrationBean.addInitParameter(ProxyServlet.P_PRESERVECOOKIES, "true");
//       Set-Cookie 服务器响应标头中保持 cookie 路径不变servletRegistrationBean.addInitParameter(ProxyServlet.P_PRESERVECOOKIEPATH, "true");
//        保持 HOST 参数不变servletRegistrationBean.addInitParameter(ProxyServlet.P_PRESERVEHOST, "true");return servletRegistrationBean;}/***接口代理*/@Beanpublic ServletRegistrationBean<ProxyServlet> servletRegistration() {ServletRegistrationBean<ProxyServlet> servletRegistrationBean = new ServletRegistrationBean<>(new ProxyServlet(), "/one/*","/two/*","three/*");servletRegistrationBean.addInitParameter(ProxyServlet.P_TARGET_URI, "http://localhost:8001/api");servletRegistrationBean.addInitParameter(ProxyServlet.P_LOG, "true");return servletRegistrationBean;}/*** 禁用springboot 自带的 HiddenHttpMethodFilter 防止post提交的form数据流被提前消费* <p>* fix springboot中使用proxyservlet的 bug.* <a href="https://github.com/mitre/HTTP-Proxy-Servlet/issues/83">bugs</a>* <a href="https://stackoverflow.com/questions/8522568/why-is-httpservletrequest-inputstream-empty">bugs</a>** @return */@Beanpublic FilterRegistrationBean<HiddenHttpMethodFilter> disableHiddenHttpMethodFilter() {FilterRegistrationBean<HiddenHttpMethodFilter> registrationBean = new FilterRegistrationBean<>();registrationBean.setFilter(new HiddenHttpMethodFilter());registrationBean.setEnabled(false); // 禁用过滤器return registrationBean;}
}

直接访问grafana代理 springboot项目端口8088报错,静态资源 路径不正确 加载失败,grafana live/ws链接也会失败,参考附录。

在这里插入图片描述
解决办法:
1.修改对应前端项目,使其 都通过代理路径。
2.可以新建项目,ProxyServlet使用 /*路径匹配规则。
3.如果这两种都不适合,那么变动最少的方案,使用nginx反向代理到ProxyServlet的代理路径上。这样做会增加一些性能损耗,但是换来了,前端项目无需更改,后端可增加接口鉴权,某些时候是值得的。

nginx配置参考:

 server {listen       8889;server_name  localhost;# grafana websocket地址代理location /api/live/ws {proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "Upgrade";proxy_set_header X-real-ip $remote_addr;proxy_set_header X-Forwarded-For $remote_addr;proxy_pass http://127.0.0.1:9999;}location / {#add_header Access-Control-Allow-Origin *;add_header Access-Control-Max-Age 1728000;add_header Access-Control-Allow-Methods 'POST,GET,OPTIONS,DELETE,PUT,HEAD,PATCH';add_header Access-Control-Allow-Headers 'satoken,DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';add_header Access-Control-Allow-Origin $http_origin;client_max_body_size 10m;if ($request_method = 'OPTIONS') {return 204;}# grafana支持配置apikey 免登录访问set $auth 'Bearer eyJrIjoiN1pKYlk5akFDZWNoMlVSUEN1YllXdm0yd2VYN2RzZFIiLCJuIjoiYWRtaW5rZXkiLCJpZCI6MX0=';# apiKey设置到header grafana免密访问proxy_set_header Authorization $auth;proxy_pass http://127.0.0.1:8088/grafana//;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;proxy_connect_timeout 600;proxy_read_timeout 600;}}

划重点

springboot 代理的/grafana/* 到 http://127.0.0.1:9999
静态资源的访问失败 404或 错误的返回html首页,是因为路径不符合此规则导致代理是失败

proxy_pass http://127.0.0.1:8088/grafana//;
由nginx代理到 // 则问题解决 ,使 /grafana/* 代理规则生效

其他访问的服务调用 nginx的这个代理

ok.
在这里插入图片描述
再看后端 日志 代理已正常
在这里插入图片描述

更安全的访问

只需要限制 原服务端口的放行规则,如仅本机可访问,然后项目增加过滤器自行判断权限。

启动类添加@ServletComponentScan扫描WebFilter,增加 Filter

import cn.dev33.satoken.stp.StpUtil;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.core.annotation.Order;import java.io.IOException;
/*** 过滤器** @author Smile*/
@Order(1)
@WebFilter(filterName = "grafanaFilter", urlPatterns = "/grafana/*")
public class ProxyGrafanaFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {Filter.super.init(filterConfig);}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {//自行 实现条件判断即可if (StpUtil.isLogin()) {// 用户已登录,继续执行过滤器链filterChain.doFilter(servletRequest, servletResponse);} else {// 用户未登录,可以返回错误信息或重定向到登录页面// 例如,返回 HTTP 401 未授权状态HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);}}@Overridepublic void destroy() {Filter.super.destroy();}
}

未登录则:
在这里插入图片描述

``收工~~

附:
grafana websocket 可能需要修改custom.ini配置

# allowed_origins is a comma-separated list of origins that can establish connection with Grafana Live.
# If not set then origin will be matched over root_url. Supports wildcard symbol "*".allowed_origins=*
或
allowed_origins = http://127.0.0.1:8889

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/102695.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

API接口文档利器:Swagger 和 接口调试利器:Postman

2.接口相关工具 2.1API接口文档利器&#xff1a;Swagger 2.1.1Swagger介绍 Swagger 是一个规范和完整的框架&#xff0c;用于生成、描述、调用和可视化 RESTful 风格的 Web 服务 (https://swagger.io/)。 它的主要作用是&#xff1a; 使得前后端分离开发更加方便&#xff0…

分类预测 | MATLAB实现S4VM半监督支持向量机二分类预测

分类预测 | MATLAB实现S4VM半监督支持向量机二分类预测 目录 分类预测 | MATLAB实现S4VM半监督支持向量机二分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 分类预测 | MATLAB实现S4VM半监督支持向量机二分类预测 程序设计 完整源码和数据获取方式&#xff1a; …

低压风机单片机方案

低压风机通常由电机、转子、机壳、进气管、出气管、齿轮和减速机等组成。电机带动转子旋转&#xff0c;旋转的转子带动齿轮和减速机转动&#xff0c;进而形成空气被吸入转子内部&#xff0c;通过旋转而产生的离心力把气体压缩&#xff0c;并将气体排出。 低压风机方案的主控型…

c++ 友元 运算符重载详解

友元 c是面向对象的&#xff0c;目的之一&#xff1a;封装 封装&#xff1a; 优点之一&#xff0c;就是安全。 缺点&#xff1a;在某些特殊的场合&#xff0c;不是很方便。 华为与IBM 40亿的咨询故事 IBM需要对华为各级部门做深度咨询分析&#xff0c; 为了提高咨询效率&a…

【MyBatis】动态SQL > 重点:${...}和#{...}与resultMap和resultType的区别

目录 一、MyBatis动态sql 1.1 动态sql的作用 1.2 动态sql作用论证 1.2.1 条件判断&#xff1a;<if> 1.2.2 循环迭代&#xff1a;<foreach> 1.2.3 SQL片段重用 1.2.4 动态条件组合&#xff1a;<choose><when><otherwise> 1.2.5 <where…

无感部署 - 蓝绿部署、AB测试、灰度发布

蓝绿部署 蓝绿部署&#xff08;Blue-Green Deployment&#xff09;是一种软件发布和部署的策略&#xff0c;旨在实现无缝的应用程序升级和回滚。在蓝绿部署中&#xff0c;同时存在两个环境&#xff1a;一个是当前稳定的生产环境&#xff08;蓝色环境&#xff09;&#xff0c;另…

设计模式(9)建造者模式

一、 1、概念&#xff1a;将一个复杂对象的构造与它的表示分离&#xff0c;使得同样的构造过程可以创建不同的表示。建造者模式主要用于创建一些复杂的对象&#xff0c;这些对象内部构建间的顺序通常是稳定的&#xff0c;但对象内部的构建通常面临着复杂的变化&#xff1b;建造…

LSTM模型

目录 LSTM模型 LSTM结构图 LSTM的核心思想 细胞状态 遗忘门 输入门 输出门 RNN模型 LRNN LSTM模型 什么是LSTM模型 LSTM (Long Short-Term Memory)也称长短时记忆结构,它是传统RNN的变体,与经典RNN相比能够有效捕捉长序列之间的语义关联,缓解梯度消失或爆炸现象.同时LS…

无涯教程-PHP - preg_split()函数

preg_split() - 语法 array preg_split (string pattern, string string [, int limit [, int flags]]); preg_split()函数的操作与split()完全相同&#xff0c;只不过正则表达式被接受为pattern的输入参数。 如果指定了可选的输入参数limit&#xff0c;则仅返回子字符串的限…

解决SEGGER Embedded Studio无法显示Nordic MCU外设寄存器问题

如果使用SES调试NRF52840的时候发现&#xff0c;官方例程只能显示CPU寄存器&#xff0c;但是无法显示外设寄存器时&#xff0c;解决办法如下&#xff1a; 1.在解决方案右键→Options→Debug→Debugger&#xff0c;然后Target Device选择正确的型号。 2.Register Definition Fil…

窗口看门狗

从下往上看: 1. 时钟设置 RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);//使能独立看门狗时钟 WWDG_SetPrescaler(WWDG_Prescaler_8);//看门狗预分频器WWDG counter clock (PCLK1/4096)/8 2.设置窗口值 实际就是设置WWDG_CR的低七位值, 但是这个值要大于0x40(也就是…

matlab 点云精配准(3)——Trimmed ICP

目录 一、算法原理1、原理概述2、参考文献二、代码实现三、结果展示四、参考链接本文由CSDN点云侠原创,matlab 点云精配准(3)——Trimmed ICP。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、算法原理 1、原理概述 见论文:[1] 李鑫,莫思特,黄华,…

MySQL高级篇——MySQL架构篇2(MySQL的数据目录)

目录 1 MySQL8的主要目录结构1.1 数据库文件的存放路径1.2 相关命令目录1.3 配置文件目录 2 数据库和文件系统的关系2.1 查看默认数据库2.2 数据库在文件系统中的表示2.3.1 InnoDB存储引擎模式2.3.2 MyISAM存储引擎模式 2.4 总结2.5 视图在文件系统中的表示2.6 其他的文件 1 My…

Redisson 分布式锁

Redis是基础客户端库&#xff0c;可用于执行基本操作。 Redisson是基于Redis的Java客户端&#xff0c;提供高级功能如分布式锁、分布式集合和分布式对象。 Redisson提供更友好的API&#xff0c;支持异步和响应式编程&#xff0c;提供内置线程安全和失败重试机制。 实现步骤…

中大许少辉博士中国建筑出版传媒八一新书《乡村振兴战略下传统村落文化旅游设计》百度百科新闻

中大许少辉博士中国建筑出版传媒八一新书《乡村振兴战略下传统村落文化旅游设计》百度百科新闻&#xff1a; 乡村振兴战略下传统村落文化旅游设计 - 百度百科 https://baike.baidu.com/item/乡村振兴战略下传统村落文化旅游设计/62588677 概览 《乡村振兴战略下传统村落文化旅游…

星际争霸之小霸王之小蜜蜂(五)--为小蜜蜂降速

目录 前言 一、思路 二、调整小蜜蜂的移速 三、限制活动范围 四、继续重构 总结 前言 前面我们已经让小蜜蜂左右移动起来了&#xff0c;而且是连续的左右移动&#xff0c;但是在使用的过程中&#xff0c;因为我使用的是笔记本电脑&#xff0c;所以屏幕比较小&#xff0c;设…

分库分表之拆分键设计 | 京东物流技术团队

众所周知&#xff0c;在现实世界中&#xff0c;每一个资源都有其提供能力的最大上限&#xff0c;当单一资源达到最大上限后就得让多个资源同时提供其能力来满足使用方的需求。同理&#xff0c;在计算机世界中&#xff0c;单一数据库资源不能满足使用需求时&#xff0c;我们也会…

Vue2-全局事件总线、消息的订阅与发布、TodoList的编辑功能、$nextTick、动画与过渡

&#x1f954;&#xff1a;高度自律即自由 更多Vue知识请点击——Vue.js VUE2-Day9 全局事件总线1、安装全局事件总线2、使用事件总线&#xff08;1&#xff09;接收数据&#xff08;2&#xff09;提供数据&#xff08;3&#xff09;组件销毁前最好解绑 3、TodoList中的孙传父&…

LRU淘汰策略执行过程

1 介绍 Redis无论是惰性删除还是定期删除&#xff0c;都可能存在删除不尽的情况&#xff0c;无法删除完全&#xff0c;比如每次删除完过期的 key 还是超过 25%&#xff0c;且这些 key 再也不会被客户端访问。 这样的话&#xff0c;定期删除和堕性删除可能都彻底的清理掉。如果…

飞天使-k8s基础组件分析-pod

文章目录 pod介绍pod 生命周期init 容器容器handlerpod中容器共享进程空间sidecar 容器共享 参考链接 pod介绍 最小的容器单元 为啥需要pod? 答: 多个进程丢一个容器里&#xff0c;会因为容器里个别进程出问题而出现蝴蝶效应&#xff0c;pod 是更高级的处理方式pod 如何共享相…