Springboot实现filter拦截token验证和跨域

2023-11-13

背景

web验证授权合法的一般分为下面几种

  • 1使用session作为验证合法用户访问的验证方式
  • 使用自己实现的token
  • 使用OCA标准

在使用API接口授权验证时,token是自定义的方式实现起来不需要引入其他东西,关键是简单实用。

合法登陆后一般使用用户UID+盐值+时间戳使用多层对称加密生成token并放入分布式缓存中设置固定的过期时间长(和session的方式有些相同),这样当用户访问时使用token可以解密获取它的UID并据此验证其是否是合法的用户。

#springboot中实现filter

  • 一种是注解filter
  • 一种是显示的硬编码注册filter

先有filter

 

import javax.servlet.annotation.WebFilter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import springfox.documentation.spring.web.json.Json;

import com.alibaba.fastjson.JSON;
 
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;



/***************
 * token验证拦截
 * @author bamboo zjcjava@163.com
 * @time 2017-08-01
 */
@Component
//@WebFilter(urlPatterns = { "/api/v/*" }, filterName = "tokenAuthorFilter")
public class TokenAuthorFilter implements Filter {

	private static Logger logger = LoggerFactory
			.getLogger(TokenAuthorFilter.class);

	@Override
	public void destroy() {

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse rep = (HttpServletResponse) response;

		//设置允许跨域的配置
		// 这里填写你允许进行跨域的主机ip(正式上线时可以动态配置具体允许的域名和IP)
		rep.setHeader("Access-Control-Allow-Origin", "*");
		// 允许的访问方法
		rep.setHeader("Access-Control-Allow-Methods","POST, GET, PUT, OPTIONS, DELETE, PATCH");
		// Access-Control-Max-Age 用于 CORS 相关配置的缓存
		rep.setHeader("Access-Control-Max-Age", "3600");
		rep.setHeader("Access-Control-Allow-Headers","token,Origin, X-Requested-With, Content-Type, Accept");


		response.setCharacterEncoding("UTF-8");
		response.setContentType("application/json; charset=utf-8");
		String token = req.getHeader("token");//header方式
		ResultInfo resultInfo = new ResultInfo();
		boolean isFilter = false;
		
			
		String method = ((HttpServletRequest) request).getMethod();
		if (method.equals("OPTIONS")) {
			rep.setStatus(HttpServletResponse.SC_OK);
		}else{
			
			
			if (null == token || token.isEmpty()) {
				resultInfo.setCode(Constant.UN_AUTHORIZED);
				resultInfo.setMsg("用户授权认证没有通过!客户端请求参数中无token信息");
			} else {
				if (TokenUtil.volidateToken(token)) {
					resultInfo.setCode(Constant.SUCCESS);
					resultInfo.setMsg("用户授权认证通过!");
					isFilter = true;
				} else {
					resultInfo.setCode(Constant.UN_AUTHORIZED);
					resultInfo.setMsg("用户授权认证没有通过!客户端请求参数token信息无效");
				}
			}
			if (resultInfo.getCode() == Constant.UN_AUTHORIZED) {// 验证失败
				PrintWriter writer = null;
				OutputStreamWriter osw = null;
				try {
					osw = new OutputStreamWriter(response.getOutputStream(),
							"UTF-8");
					writer = new PrintWriter(osw, true);
					String jsonStr = JSON.toJSONString(resultInfo);
					writer.write(jsonStr);
					writer.flush();
					writer.close();
					osw.close();
				} catch (UnsupportedEncodingException e) {
					logger.error("过滤器返回信息失败:" + e.getMessage(), e);
				} catch (IOException e) {
					logger.error("过滤器返回信息失败:" + e.getMessage(), e);
				} finally {
					if (null != writer) {
						writer.close();
					}
					if (null != osw) {
						osw.close();
					}
				}
				return;
			}
			
			if (isFilter) {
			logger.info("token filter过滤ok!");
			chain.doFilter(request, response);
			}
		}
			
		
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {

	}

}

注解配置filter

加上如下配置则启动时会根据注解加载此filter
@WebFilter(urlPatterns = { “/api/*” }, filterName = “tokenAuthorFilter”)

硬编码注册filter

在application.java中加入如下代码


    //注册filter
    @Bean  
    public FilterRegistrationBean  filterRegistrationBean() {  
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();  
        TokenAuthorFilter tokenAuthorFilter = new TokenAuthorFilter();  
        registrationBean.setFilter(tokenAuthorFilter);  
        List<String> urlPatterns = new ArrayList<String>();  
        urlPatterns.add("/api/*");
        registrationBean.setUrlPatterns(urlPatterns);  
        return registrationBean;  
    }  

以上两种方式都可以实现filter

跨域说明

springboot可以设置全局跨域,但是对于filter中的拦截地址并不其中作用,因此需要在dofilter中再次设置一次

区局设置跨域方式如下
##方式1.在application.java中加入如下代码

	//跨域设置
	private CorsConfiguration buildConfig() {  
        CorsConfiguration corsConfiguration = new CorsConfiguration();  
        corsConfiguration.addAllowedOrigin("*");  
        corsConfiguration.addAllowedHeader("*");  
        corsConfiguration.addAllowedMethod("*");  
        
        
        
        return corsConfiguration;  
    }  
      
    /** 
     * 跨域过滤器 
     * @return 
     */  
    @Bean  
    public CorsFilter corsFilter() {  
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();  
        source.registerCorsConfiguration("/**", buildConfig()); // 4  
        return new CorsFilter(source);  
    }  

方式2.配置注解

必须集成WebMvcConfigurerAdapter类


/**********
 * 跨域 CORS:使用 方法3
 * 方法:
	1服务端设置Respone Header头中Access-Control-Allow-Origin
	2配合前台使用jsonp
	3继承WebMvcConfigurerAdapter 添加配置类
	http://blog.csdn.net/hanghangde/article/details/53946366
 * @author xialeme
 *
 */
@Configuration  
public class CorsConfig extends WebMvcConfigurerAdapter{  
  
   /* @Override  
    public void addCorsMappings(CorsRegistry registry) {  
        registry.addMapping("/**")  
                .allowedOrigins("*")  
                .allowCredentials(true)  
                .allowedMethods("GET", "POST", "DELETE", "PUT")  
                .maxAge(3600);  
    }  */
  
	private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*"); // 1
        corsConfiguration.addAllowedHeader("*"); // 2
        corsConfiguration.addAllowedMethod("*"); // 3
        return corsConfiguration;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig()); // 4
        return new CorsFilter(source);
    }
  
    
} 

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Springboot实现filter拦截token验证和跨域 的相关文章

  • 使用 API 密钥和机密保护 Spring Boot API

    我想保护 Spring Boot API 的安全 以便只有拥有有效 API 密钥和秘密的客户端才能访问它 但是 程序内部没有身份验证 使用用户名和密码的标准登录 因为所有数据都是匿名的 我想要实现的目标是所有 API 请求只能用于特定的第三
  • 尝试使用 Spring boot CLI 加密时出现错误“‘encypt’不是有效命令”

    我正在尝试使用 Spring boot CLI 1 5 7 加密密码 spring encrypt mysecret key ashish 我收到此命令的以下错误 encypt is not a valid command See help
  • 使用 Spring Boot 进行 Kafka 流

    我想在我的 Spring Boot 项目中使用 Kafka Streams 实时处理 所以我需要 Kafka Streams 配置或者我想使用 KStreams 或 KTable 但我在互联网上找不到示例 我做了生产者和消费者 现在我想实时
  • Android SQLite 数据库从查询中删除重复项

    我是 SQLite 新手 我使用此查询是为了从特定用户的列中提取所有行 Cursor c db query true TABLE COLUMN USER user null null null null null 这是表格的示例 group
  • Spring SpEL - 用于创建字符串和自定义对象映射的表达式语言

    我在用着春季启动从属性文件中读取以下内容的示例 sub region data AF subRegionCd 34 subRegionName Southern Asia subRegionDesc status A 我在下面使用过 但不起
  • Spring @ComponentScan 不适用于 @Repository

    我的存储库与配置类位于不同的包中 因此我使用 Repostiory 将其注释为以下内容 package test Repository public interface UserTest extends JpaRepository
  • 在 Spring Boot 应用程序中启用 Spring 框架的日志记录

    我已经使用 spring boot 创建了简单的网络应用程序 我想为 springframework 包启用调试日志 我知道如何在普通 spring mvc 项目中启用日志记录 我在这里尝试了相同的操作 但它不起作用 有人可以帮我吗 我的
  • Python Pandas 根据另一列的总计从另一个数据帧中选择值

    我下面有一个 DataFrame 但我需要根据取消和订单列从每个代码中选择行 假设代码 xxx 的阶数为 6 1 5 1 阶数为 11 我需要一种算法 可以选择满足总共 11 行的行 阶数为 6 5 如果没有行匹配 则选择最接近的 id 并
  • 如何在 Spring Mvc 项目中设置上下文根

    我在 Tomcat 服务器中使用 Spring MVC 项目 每次运行应用程序时 服务器上下文根都会更改 如何设置固定上下文根 我的项目名称是 DemoApplication 首先部署此上下文根 路径是 http localhost 808
  • 将 RequestBody json 转换为对象 - Spring Boot

    我是 java 开发的初学者 但之前有 PHP 和 Python 等编程语言的经验 对于如何进行 Spring Boot 的开发几乎没有什么困惑 我正在开发一个rest API 它有以下请求 key value key1 value1 pl
  • Jackson 的 ObjectMapper 和 SQL 中的 RowMapper

    我们正在使用对象映射器 当将 ObjectMapper 与 RowMapper 一起使用时 是否应该在每个 mapRow 内部 如下所示 声明它 还是在 mapRow 外部声明为类公共成员 我认为根据本文 它应该作为公共类成员在外部 我应该
  • 使用 Spring Boot 和 jHipster 实现多个资源服务器的 OAuth2 SSO

    所以 我有一个 oAuth2 应用程序 它是 jHipster 应用程序 使用 mongodb 我想将 3 个资源应用程序连接到该应用程序 但它们都应共享相同的用户群 以便用户只能登录一次 有没有办法使用 jHipster 在 Spring
  • CrudRepository 未从 schema.sql 读取数据

    Setup 我有一个带有简单 Entity Customer 对象和 CustomerRepository 的 spring boot 应用程序 我想用描述的测试数据预加载数据库在我的另一个问题中 https stackoverflow c
  • OutputCapture 进行多次测试

    我正在使用 org springframework boot test OutputCapture 来测试记录某些内容的注释 它对于单个测试非常有效 当单独运行测试时 如果源文件中存在使用输出捕获的多个测试 但是当多个测试一起运行时 只有第
  • 使用HTTP/2协议时如何传递Keep-alive元数据?

    我有一个angular使用带有嵌入式 Spring Boot 的 Web 应用程序tomcat服务器在后端 我想让已建立的 http 连接保持更长时间 以提高后续 http 请求的响应时间 和http 1 1浏览器被告知通过添加来保持 ht
  • 如何防止嵌入式netty服务器使用spring-boot-starter-webflux启动?

    我想使用 Springs 新的反应式在客户端和服务器应用程序之间建立通信webflux扩大 对于依赖管理我使用gradle 我在服务器和客户端上的 build gradle 文件基本上是 buildscript repositories m
  • Maven 配置文件相当于 Gradle

    我试图在我的 spring boot 项目构建中实现一个简单的场景 包括 排除依赖项以及根据环境打包 war 或 jar 例如 对于环境dev包括开发工具和包 jar 用于prod包战等 我知道它不再是基于 XML 的配置 我基本上可以在
  • 在 th:href 链接中使用模型属性

    有没有办法在 th href 链接中引用模型属性 例如 a a Here 当前用户是控制器中指定的模型变量 这可以很容易地访问 如th text标签 但是 那th href百里香解析失败 如果有任何方法以这种方式引用模型属性 则在th hr
  • spring boot框架下如何过滤tomcat产生的访问日志

    我们使用spring boot框架 通过嵌入式tomcat生成访问日志 访问日志的格式如下 server tomcat access log enabled true server tomcat access log pattern h l
  • Spring OAuth redirect_uri 不使用 https

    我有一个 Spring Boot 1 3 0 应用程序 其中包含 Spring Security OAuth 作为一种 SSO 集成 问题是应用程序在非 SSL 环境中运行 负载均衡器 F5 后面有一个非标准端口 强制使用 SSL 并且 O

随机推荐

  • 解决使用VS2015新建QT界面之后cpp文件提示“不允许使用不完整的类型”问题

    解决使用VS2015新建QT界面之后cpp文件提示 不允许使用不完整的类型 问题 问题描述 分析解决过程 总结 问题描述 分析解决过程 检查了半天跟另外一个文件的结构是一模一样的 只是类名不一样 网上找了很多方式都不行 真是让我脑热 后面我
  • 微信提示在客户端提交验证_微信提示非常用设备登陆需输入短信验证码的解决方法...

    已绑定邮箱 1 已设置独立密码 请您直接通过微信号 独立密码登录即可 2 未设置独立密码 可通过以下两种方式设置独立密码后登录 1 请您可以在登录界面输入微信号 点击 忘记密码 通过手机号验证码或邮箱重设密码 2 通过电脑登录weixin
  • C语言:运算表达式

    目录 一 赋值运算符与赋值表达式 二 逗号运算符和逗号运算符 三 关系运算符和关系表达式 四 逻辑运算符和逻辑表达式 五 条件运算符和条件表达式 六 scanf错误解决 七 总结 一 赋值运算符与赋值表达式 变量 表达式 特点 自右向左 a
  • rsync备份

    Rsync的特点和优点 可以镜像保存整个目录树和文件系统 可以很容易做到保持原来文件的权限 时间 软硬链接等等 无须特殊权限即可安装 快速 第一次同步时 rsync 会复制全部内容 但在下一次只传输修改过的文件 压缩传输 rsync 在传输
  • xss检测工具XSStrike

    一 下载安装 下载地址 https github com s0md3v XSStrike最新版支持python3windows linux系统都可以运行完成下载之后 进入XSStrike目录 cd XSStrike接下来使用如下命令安装依赖
  • Quartus II建立新工程流程,Quartus如何建立工程?

    在用Quartus Quartus Prime 18 0 Standard Edition开发一个项目时 首先要建立一个工程文件 这个工程文件包含了项目设计过程中生成的所有文件 创建的步骤大致如下 3 1 首先双击Quartus Quart
  • RISC-V IDE MounRiver Studio相较Eclipse GNU的区别与改进

    RISC V单片机集成开发环境 IDE MounRiver Studio相较Eclipse GNU的区别与改进 一 界面与功能区别 1 欢迎页 MounRiver Studio www mounriver com 左侧为工程操作及帮助文档快
  • 机器学习(二)分类器及回归拟合

    在机器学习中 分类器作用是在标记好类别的训练数据基础上判断一个新的观察样本所属的类别 分类器依据学习的方式可以分为非监督学习和监督学习 非监督学习顾名思义指的是给予分类器学习的样本但没有相对应类别标签 主要是寻找未标记数据中的隐藏结构 监督
  • 互补品的需求曲线图_需求曲线:需求曲线的移动

    我们已经知道市场需求量是社会中各个家庭或企业的需求总和 那么需求曲线的变动是什么因素引起的呢 这将是我们本次讨论的重点问题 我们在讨论市场需求需求曲线时假设的前提 其他条件都保持不变 但是随着时间的推移 该曲线不一定是稳定不变的 如果某种因
  • js双层循环拿到二层循环的index值

    情景描述 多个房间 每个房间的人数不尽相同 后端获取的数据格式是根据房间走的 如 data roomNo 201 guestList name 张三 name 李四 roomNo 202 guestList name 张三三 name 李四
  • 销售系统服务器,勤哲Excel服务器-销售管理系统(9页)-原创力文档

    勤哲 Excel 服务器 销售管理系统 一 系统框架 整个系统分为五部分 基础数据 销售管理 仓库管理 费用管理 经营分析 其中仓 库管理的详细系统可以参见 库存管理系统 本系统不做详细说明 二 各模块功能说明 一 基础数据 1 仓库信息
  • 抖音评论获取与回复源码项目

    这个项目分享的如何基于抖音平台 开发的java源码 API覆盖率超过95 只需要简单的修改一下配置文件 就能轻松调用api 自动集成官方SDK 切换使用原生一样方便 多种选择 轻松适配 根据视频大小 自动切换视频分片上传 轻松避免异常 保证
  • 队列 - Queue

    1 队列概述 1 队列 又称为伫列 Queue 计算机科学中的一种抽象资料型别 是先进先出 FIFO First In First Out 的线性表 队列是一种特殊的线性表 特殊之处在于它只允许在表的前端 front 进行删除操作 在表的后
  • centos8普通用户在自己的用户目录下安装CUDA和cudnn,安装pytorch

    1 查看系统的cuda驱动 nvidia smi 2 cuda官网下载比上面的cuda版本低的CUDA 根据系统版本选择对应的runfile 注意因为是非root用户 不要用sudo的rpm安装 选择下载runfile用sh安装 输入官网的
  • 分布式数据库-TiDB应用场景简介

    前言 最近公司要讨论分库分表 正好一起参加了培训 一般mysql单表数据库容量达到一定的极限 性能会急剧下降 之前工作的时候已经大佬们高喊几次了分库分表 但是最终没能实现或者落地的方案不佳 在这里一篇很好的文章指出了当前开源的分库分表的框架
  • C#输入输出

    目录 一 函数介绍 二 C 中输入输出的一些例子 一 函数介绍 C Console 类主要用于控制台应用程序的输入和输岀操作 Console Read 和Console ReadLine 的区别在于 前者读取是根据空白符隔开且返回int类型
  • JavaScript delete 方法之(删除对象中的某个元素)

    delete方法用于删除对象的指定元素 包括变量和函数 示例 删除对象中的某个属性 后台返回一个对象 data total 6 法人 1 可公示 2 个人 1 国家类型 1 非国家类型 1 非公示 0 而我不需要total这个属性 需要把它
  • FDAtool转C

    1 首先设计低通滤波器 在simulink里面仿真 得到滤波器系数 并生成头文件 解得差分方程 acc xxx index IIR A 2 acc xxx index 1 IIR A 3 acc xxx index 2 IIR A 4 ac
  • java消息订阅_小程序订阅消息推送(含源码)java实现小程序推送,springboot实现微信消息推送...

    小程序订阅消息推送 含源码 java实现小程序推送 springboot实现微信消息推送 发布时间 2020 04 04 19 42 47 来源 51CTO 阅读 704 作者 wx5cef8dfc0aa1c 前面写过一篇云开发实现小程序订
  • Springboot实现filter拦截token验证和跨域

    文章目录 背景 注解配置filter 硬编码注册filter 跨域说明 方式2 配置注解 背景 web验证授权合法的一般分为下面几种 1使用session作为验证合法用户访问的验证方式 使用自己实现的token 使用OCA标准 在使用API