当前位置: 首页 > news >正文

自定义SpringMVC拦截器,实现内外网访问控制功能

这篇文章简单介绍如何自定义一个SpringMVC拦截器,并通过拦截器实现具体的功能。

首先,需要创建一个自定义的拦截器类,该类实现HandlerInterceptor接口。

package cn.edu.sgu.www.mhxysy.interceptor;import cn.edu.sgu.www.mhxysy.feign.FeignService;
import cn.edu.sgu.www.mhxysy.property.NetworkProperties;
import cn.edu.sgu.www.mhxysy.restful.JsonResult;
import cn.edu.sgu.www.mhxysy.restful.ResponseCode;
import cn.edu.sgu.www.mhxysy.util.IpUtils;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;/*** 自定义拦截器* @author heyunlin* @version 1.0*/
@Slf4j
@Component
public class WebInterceptor implements HandlerInterceptor {@Value("${spring.application.name}")private final String service = "mhxysy";/*** 匿名接口权限*/private static Set<String> ANONYMITY_URLS;private final NetworkProperties networkProperties;@Autowiredpublic WebInterceptor(FeignService feignService, NetworkProperties networkProperties) {this.networkProperties = networkProperties;if (ANONYMITY_URLS == null) {List<String> permissions = feignService.selectAnonymityPermissions(service);ANONYMITY_URLS = new HashSet<>(permissions);}}@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {// 获取请求urlString requestURI = request.getRequestURI();// 1、处理匿名访问接口,直接跳过鉴权if (ANONYMITY_URLS.contains(requestURI)) {log.debug("匿名接口" + requestURI + "正在被访问...");return true;}// 2、内外网控制if (networkProperties.isEnableInnerIpAccess()) {// 得到客户端IPString clientIp = IpUtils.getIp();if (!networkProperties.getInnerIps().contains(clientIp)) {// 构建返回对象JsonResult<Void> jsonResult = JsonResult.error(ResponseCode.FORBIDDEN, requestURI + "只允许内网访问~");// 设置内容类型为jsonresponse.setContentType("application/json;charset=utf-8");// 设置响应状态码response.setStatus(ResponseCode.FORBIDDEN.getValue());response.getWriter().write(JSON.toJSONString(jsonResult));return false;}}return true;}/*** 获取匿名接口列表* @return Set<String>*/public static Set<String> getAnonymityUrls() {return ANONYMITY_URLS;}}

IpUtils.java

package cn.edu.sgu.www.mhxysy.util;import javax.servlet.http.HttpServletRequest;/*** ip地址工具类* @author heyunlin* @version 1.0*/
public class IpUtils {/*** 获取客户端IP* @return String*/public static String getIp() {HttpServletRequest request = UserUtils.getRequest();String ip = request.getHeader("x-forwarded-for");if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("Proxy-Client-IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("WL-Proxy-Client-IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("HTTP_CLIENT_IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("HTTP_X_FORWARDED_FOR");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("X-Real-IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getRemoteAddr();}return ip;}/*** 获取浏览器类型* @return String 浏览器类型*/public static String getBrowserType() {HttpServletRequest request = UserUtils.getRequest();String type = "其它";String browserName = request.getHeader("USER-AGENT").toLowerCase();if (browserName.indexOf("msie") > 0) {type = "IE";} else if (browserName.indexOf("firefox") > 0) {type = "Firefox";} else if (browserName.indexOf("chrome") > 0) {type = "Chrome";} else if (browserName.indexOf("opera") > 0) {type = "Opera";} else if (browserName.indexOf("gecko") > 0 && browserName.indexOf("rv:11") > 0) {type = "IE11";}return type;}}

然后把拦截器注册到SpringMVC

package cn.edu.sgu.www.mhxysy.config;import cn.edu.sgu.www.mhxysy.interceptor.WebInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import javax.servlet.ServletContext;/*** springmvc配置类* @author heyunlin* @version 1.0*/
@Configuration
public class SpringMvcConfig implements WebMvcConfigurer {@Value("${uploads.path}")private String uploadPath;private final WebInterceptor webInterceptor;@Autowiredpublic SpringMvcConfig(WebInterceptor webInterceptor) {this.webInterceptor = webInterceptor;}/*** 解决跨域问题*/@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOrigins("*").allowedMethods("*").allowedHeaders("*").allowCredentials(true).maxAge(5000);}/*** 添加静态资源路径*/@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {// 配置静态资源路径registry.addResourceHandler("/**").addResourceLocations("classpath:static/").addResourceLocations("file:" + uploadPath + "/");// 解决knife4j访问失败问题registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");}@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(webInterceptor).addPathPatterns("/**");}/*** 设置SESSION_ID* @return ServletContextInitializer*/@Beanpublic ServletContextInitializer servletContextInitializer() {return new ServletContextInitializer() {@Overridepublic void onStartup(ServletContext servletContext) {servletContext.getSessionCookieConfig().setName("MHXYSY_JSESSIONID");}};}}

相关文章:

自定义SpringMVC拦截器,实现内外网访问控制功能

这篇文章简单介绍如何自定义一个SpringMVC拦截器&#xff0c;并通过拦截器实现具体的功能。 首先&#xff0c;需要创建一个自定义的拦截器类&#xff0c;该类实现HandlerInterceptor接口。 package cn.edu.sgu.www.mhxysy.interceptor;import cn.edu.sgu.www.mhxysy.feign.Fei…...

在pycharm中配置GPU训练环境(Anaconda)(yolov5)

目录 1. 具体的配置过程&#xff1a; 2. 在指定位置&#xff08;路径&#xff09;创建虚拟环境&#xff1a; 3. conda常用命令&#xff1a; 4: 在跑模型时候遇到的一些问题&#xff1a; 4.1: conda添加python解释器找不到对应的python.exe文件 4.2: 报错“OSError: [WinErr…...

【LeetCode刷题-链表】--146.LRU缓存

146.LRU缓存 方法一&#xff1a;哈希表双向链表 使用一个哈希表和一个双向链表维护所有在缓存中的键值对 双向链表按照被使用的顺序存储了这些键值对&#xff0c;靠近头部的键值对是最近使用的&#xff0c;而靠近尾部的键值对是最久使用的哈希表即为普通的哈希映射&#xff0…...

mysql 问题解答

01 Mysql有哪些数据类型 MySQL支持多种数据类型,这些类型可以分为几个大的类别:数值类型、日期和时间类型、字符串(字符和字节)类型、空间类型、JSON类型。下面是每种类型的简要说明和用途,以及示例。 数值类型 整型: TINYINT:非常小的整数,如性别标识(0代表女性,1代…...

组件与Props:React中构建可复用UI的基石

目录 组件&#xff1a;构建现代UI的基本单位 Props&#xff1a;组件之间的数据传递 Props的灵活性&#xff1a;构建可配置的组件 组件间的通信&#xff1a;通过回调函数传递数据 总结&#xff1a; 组件&#xff1a;构建现代UI的基本单位 组件是前端开发中的关键概念之一。…...

接口框架第二篇—unittest/pytest 有什么区别

1.用例编写方法 unittest 1&#xff09;测试文件必须导入unittest包 2&#xff09;测试类必须继承unittest.TestCase 3&#xff09;测试类必须有unittest.main()方法 4&#xff09;测试方法必须要以test_打头 pytest 1&#xff09;测试文件名要以test_打头&#xff0c;或…...

Window 7 / 10 / 11 .bat .cmd 中文路径不识别解决方案

一般都是编码问题 我们在批处理的第一行加入: chcp 65001 进行转为UTF-8 编码就可以实现中文路径识别...

Linux命令(113)之rev

linux命令之rev 1.rev介绍 linux命令rev是将文件中的每行内容已字符为单位反向输出&#xff0c;即第一个字符最后输出&#xff0c;最后一个字符最先输出 2.rev用法 rev [参数] filename rev参数 参数说明-V显示版本信息-h显示帮助信息 3.实例 3.1.显示rev的版本信息 命令…...

QT+SQLite数据库配置和使用

一、简介 1.1 SQLite&#xff08;sql&#xff09;是一款开源轻量级的数据库软件&#xff0c;不需要server&#xff0c;可以集成在其他软件中&#xff0c;非常适合嵌入式系统。Qt5以上版本可以直接使用SQLite&#xff08;Qt自带驱动&#xff09;。 二、下载和配置 2.1 SQLite下载…...

若依分离版——配置多数据源(mysql和oracle),实现一个方法操作多个数据源

目录 一、若依平台配置 二、编写oracle数据库访问的各类文件 三. 一个方法操作多个数据源 一、若依平台配置 1、在ruoyi-admin的pom.xml添加依赖 <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> <version…...

Seata入门系列【19】分布式事务之CAP、BASE理论

1 CAP理论 CAP是以下三个词语的缩写&#xff1a; Consistency&#xff1a;一致性Availability&#xff1a;可用性Partition tolerance&#xff1a;分区容忍性 CAP理论的基础概念就是在分布式系统中&#xff0c;无法同时满足以上三点。 下面我们以一个简单的分布式系统&…...

界面控件DevExpress WPF Gauge组件 - 轻松实现个性化商业仪表盘

DevExpress WPF Gauge&#xff08;仪表&#xff09;控件包含了多种圆形仪表类型、水平和垂直线性仪表、分段和矩阵数字仪表以及状态指示器&#xff0c;同时还具有最终用户交互性的集成支持。 P.S&#xff1a;DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至…...

算法题:870. 优势洗牌

该算法是临时想出来的&#xff0c;Java代码的实现在时间上不占优&#xff0c;之后有时间要优化一下&#xff0c;目前就是给大家提供一下思路。 解题思路&#xff1a;田忌赛马的思想 贪心法。 Step1. 对两个数组进行排序。 Step2. 同时遍历排序后的nums2和nums1&#xff0c;将…...

[架构之路-252/创业之路-83]:目标系统 - 纵向分层 - 企业信息化的呈现形态:常见企业信息化软件系统 - 企业应用信息系统集成

目录 第一章 什么是企业应用信息系统集成What 1.1 简介 1.2 架构 二、为什么需要企业应用信息系统集成Why 三、如何实现企业应用信息系统集成 3.1 步骤 3.2 企业应用集成的层次 3.3 业务流程重组 第一章 什么是企业应用信息系统集成What 1.1 简介 企业应用信息系统集…...

MFC发送http https以及json解析

域名解析成IP char szWeb[128] "www.baidu.com";struct hostent *pHost NULL;pHost gethostbyname(szWeb);//完成主机名到域名的解析char *IP inet_ntoa(*((struct in_addr *)pHost->h_addr));CString ipStr IP;请求三部曲&#xff1a; 1、CInternetSession…...

UE5加载websocket模块为空

今天测试UE 发现工程启动不了&#xff0c;后来看到原来是websocket模块无法加载。 解决的它的方法很简单&#xff0c;这种问题一般会出现在源码版本的引擎或者是停电了&#xff0c;导致UElaunch版本损坏&#xff0c;解决方法是来到源码版本的引擎 这个目录下&#xff1a; D:\…...

学习 Python 数据可视化,如何快速入门?

Python 是一种非常流行的编程语言&#xff0c;具有简单易学、高效、丰富的库和工具等特点。其中&#xff0c;数据可视化是 Python 的一个重要应用领域&#xff0c;可以帮助人们更好地理解和分析数据。本文将介绍如何快速入门 Python 数据可视化&#xff0c;以及常用的可视化工具…...

XUbuntu22.04之simplenote支持的Markdown语法总结(一百九十一)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…...

JAVA深化篇_26——Apache commons-io工具包的使用

Apache commons-io工具包的使用 Apache基金会介绍 Apache软件基金会&#xff08;也就是Apache Software Foundation&#xff0c;简称为ASF&#xff09;&#xff0c;是专门为支持开源软件项目而办的一个非盈利性组织。在它所支持的Apache项目与子项目中&#xff0c;所发行的软…...

centos 7 kafka2.6单机安装及动态认证SASL SCRAM配置

目录 1.kfaka安装篇 1.1 安装jdk 1.2安装kafka 2.安全篇 2.1 kafka安全涉及3部份&#xff1a; 2.2 Kafka权限控制认证方式 2.3 SASL/SCRAM-SHA-256 配置实例 2.3.1 创建用户 2.3.2 创建 JAAS 文件及配置 3.测试 3.1 创建测试用户 3.2 配置JAAS 文件 3.2.1 生产者配…...

TrafficWatch 数据包嗅探器工具

TrafficWatch 是一种数据包嗅探器工具&#xff0c;允许您监视和分析 PCAP 文件中的网络流量。它提供了对各种网络协议的深入了解&#xff0c;并可以帮助进行网络故障排除、安全分析等。 针对 ARP、ICMP、TCP、UDP、DNS、DHCP、HTTP、SNMP、LLMNR 和 NetBIOS 的特定于协议的数据…...

MySQL Binlog实战应用之一

一、前言 开发业务系统尤其是与财务相关的系统&#xff0c;需要记录每一笔变更操作的日志&#xff0c;这一般有两种实现方案。 1、代码中通过AOP实现&#xff0c;提供注解跟踪记录日志&#xff0c;这种方案能够比较清晰地以业务角度记录操作日志&#xff0c;但记录变更前的旧…...

【MySQL】MVCC机制(undo log,read view)

文章目录 前言一. 预备知识二. 模拟MVCC三. Read View四. RC与RR的本质区别结束语 前言 MVCC&#xff08;多版本并发控制&#xff09;是一种用来解决读-写冲突的无锁并发控制 MVCC为事务分配单向增长的事务ID&#xff0c;为每个修改保存一个版本&#xff0c;版本与事物ID相关联…...

gma 2 教程(三)坐标参考系统:3.投影方法

安装 gma&#xff1a;pip install gma 地图投影是利用一定数学法则把地球表面的经、纬线转换到平面上的理论和方法。由于地球是一个赤道略宽两极略扁的不规则的梨形球体&#xff0c;故其表面是一个不可展平的曲面&#xff0c;所以运用任何数学方法进行这种转换都会产生误差和变…...

蓝桥杯每日一题2023.11.2

题目描述 等差素数列 - 蓝桥云课 (lanqiao.cn) 题目分析 对于此题我们需要求出最小的公差并且长度为10&#xff0c; 1.确保序列开始为素数 2.确定枚举的个数 注意&#xff1a;序列中数只是d的变化&#xff0c;可以通过此计算将开始数字后9个数字都计算出来&#xff0c;d是…...

Leetcode67二进制求和

1104 代码&#xff1a; class Solution {public String addBinary(String a, String b) {StringBuffer ans new StringBuffer();int n Math.max(a.length(),b.length()),carry 0;for(int i0;i<n;i){carry i < a.length()?(a.charAt(a.length()-1-i)-0):0;carry i…...

线性代数 第五章 特征值与特征向量

一、特征值定义 二、特征值求法 定义法&#xff1b;&#xff1b;相似。 三、特征向量求法 定义法&#xff1b;基础解系法&#xff1b;&#xff1b;相似。 四、特征值性质 不同特征值的特征向量线性无关k重特征值至多有k个线性无关的特征向量 五、相似的定义 若&#xff…...

Python嵌入式数据库 / 轻量级数据库 / 小型数据库介绍(SQLite、Pandas DataFrame、TinyDB)(python数据库)

文章目录 Python嵌入式数据库/轻量级数据库介绍什么是嵌入式数据库/轻量级数据库&#xff1f;SQLitePandasTinyDB总结 Python嵌入式数据库/轻量级数据库介绍 在构建应用程序时&#xff0c;数据存储是必不可少的一部分。传统的方式是使用如MySQL、PostgreSQL这样的重量级数据库…...

USB PD v1.0快速充电通信原理

1 原理 本篇文章讲的快速充电是指USB论坛所发布的USB Power Delivery快速充电规范&#xff08;通过VBUS直流电平上耦合FSK信号来请求充电器调整输出电压和电流的过程&#xff09;&#xff0c;不同于本人发布的另一篇文章所讲的高通Quick Charger 2.0规范&#xff0c;因为高通QC…...

【华为】路由器以PPPoE拨号接入广域网

组网需求 用户希望以PPPoE拨号方式接入广域网&#xff0c;如图1所示&#xff0c;Router作为PPPoE客户端&#xff0c;得到PPPoE服务器的认证后获得IP地址&#xff0c;实现用户接入互联网的需求。内网网关地址&#xff08;即VLANIF1接口的IP地址&#xff09;为10.137.32.1/24。 …...