Springboot实现filter拦截token验证和跨域
背景
web验证授权合法的一般分为下面几种
- 使用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("*"); //
corsConfiguration.addAllowedHeader("*"); //
corsConfiguration.addAllowedMethod("*"); //
return corsConfiguration;
} @Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig()); //
return new CorsFilter(source);
} }
Springboot实现filter拦截token验证和跨域的更多相关文章
- vue+springboot前后端分离实现单点登录跨域问题处理
最近在做一个后台管理系统,前端是用时下火热的vue.js,后台是基于springboot的.因为后台系统没有登录功能,但是公司要求统一登录,登录认证统一使用.net项目组的认证系统.那就意味着做单点登 ...
- 基于 HTTP 请求拦截,快速解决跨域和代理 Mock
近几年,随着 Web 开发逐渐成熟,前后端分离的架构设计越来越被众多开发者认可,使得前端和后端可以专注各自的职能,降低沟通成本,提高开发效率. 在前后端分离的开发模式下,前端和后端工程师得以并行工作. ...
- 基于JWT的web api身份验证及跨域调用实践
随着多终端的出现,越来越多的站点通过web api restful的形式对外提供服务,很多网站也采用了前后端分离模式进行开发,因而在身份验证的方式上可能与传统的基于cookie的Session Id的 ...
- Cookie、Session、Token与JWT(跨域认证)
之前看到群里有人问JWT相关的内容,只记得是token的一种,去补习了一下,和很久之前发的认证方式总结的笔记放在一起发出来吧. Cookie.Session.Token与JWT(跨域认证) 什么是Co ...
- Springboot 项目源码 vue.js html 跨域 前后分离 shiro权限
官网:www.fhadmin.org 特别注意: Springboot 工作流 前后分离 + 跨域 版本 (权限控制到菜单和按钮) 后台框架:springboot2.1.2+ activiti6.0 ...
- springboot WebMvcConfigurer配置静态资源和解决跨域
前言 虽然现在都流行前后端分离部署,但有时候还是需要把前端文件跟后端文件一起打包发布,这就涉及到了springboot的静态资源访问的问题.不单只是静态资源打包,比如使用本地某个目录作为文件存储,也可 ...
- 不用调整Nginx,SpringBoot也能解决前端访问的跨域问题
1.什么情况下会出现跨域问题 通常,在前端工程师的开发过程中,往往在本地机器启动前端服务, 而调用的后端接口服务是在另外一台机器运行,这时就会出现跨域问题,让接口无法调通. 而到了测试环境和生产环境, ...
- Spring Boot配置拦截器及实现跨域访问
拦截器功能强大,能够深入方法前后,常应用于日志记录.权限检查和性能检测等,几乎是项目中不可或缺的一部分,本文就来实现Spring Boot自定义拦截器的配置. 理论指导 问:Spring Boot怎么 ...
- SpringBoot入门教程(十三)CORS方式实现跨域
什么是跨域?浏览器从一个域名的网页去请求另一个域名的资源时,域名.端口.协议任一不同,都是跨域 . 跨域资源访问是经常会遇到的场景,当一个资源从与该资源本身所在的服务器不同的域或端口请求一个资源时,资 ...
随机推荐
- POJ - 3279 Fliptile (枚举)
http://poj.org/problem?id=3279 题意 一个m*n的01矩阵,每次翻转(x,y),那么它上下左右以及本身就会0变1,1变0,问把矩阵变成全0的,最小需要点击多少步,并输出最 ...
- Linux - rar 压缩
Linux - rar yum -y install libstdc++.so. wget http://rarsoft.com/rar/rarlinux-4.0.1.tar.gz cd rar ma ...
- 寻路优化(二)——二维地图上theta*算法的设计探索
这篇文章是基于上一篇文章的研究上进行的,使得路径更加的平滑和自然,特此记录.有错误欢迎大家批评指正.如需转载请注明出处,http://www.cnblogs.com/Leonhard-/p/68660 ...
- 啊金学习javascript系列一之javascript整体印象
javascript是一门编程语言,这个是第一个观点.是编程语言,那就拥有编程语言的功能.在我理解之中,编程语言是和计算机打交道的语言,就是我们跟计算机说话用的语言,是用来指挥计算机的.人类能够理解语 ...
- Javascript定义变量
在JavaScript中通过var来定义变量,不管是数字还是字符串,都可以通过这种方式来定义:我们既可以在声明变量的同时给变量赋值,也可以先声明变量,再给变量赋值. <script> va ...
- SpringBoot整合定时任务和异步任务处理 3节课
1.SpringBoot定时任务schedule讲解 定时任务应用场景: 简介:讲解什么是定时任务和常见定时任务区别 1.常见定时任务 Java自带的java.util.Timer类 ...
- Dubbo监控中心
(1).dubbo-admin(管理控制台) 1).从https://github.com/apache/incubator-dubbo-ops下载解压 2).修改dubbo-admin配置文件中zo ...
- BackBone结合ASP.NET MVC实现页面路由操作
1. 问题的背景 什么是页面路由操作,就是通过浏览器地址栏的标记来实现页面内部的一些操作,这些操作具有异步性和持久性.应用场景主要有页面操作过程中的添加收藏夹的操作.后退操作等过程中能完全恢复界面. ...
- 【ARTS】01_03_左耳听风-20181126~1202
ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 Algo ...
- 【逆向笔记】OD工具使用-逆向TraceMe.exe
名词注释 System breakpoint:系统断点,OllyDbg用CreateProcessA加载DEBUG_ONLY_THIS_PROCESS参数执行,程序运行之后会触发一个INT13,在系统 ...