文档章节

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

f
 funnymin
发布于 2018/10/16 06:47
字数 979
阅读 43
收藏 1

背景

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);
    }



 

本文转载自:https://blog.csdn.net/zjcjava/article/details/78237164

共有 人打赏支持
f
粉丝 0
博文 6
码字总数 101
作品 0
常州
私信 提问
Spring Boot学习笔记

多模块开发 [SpringBoot学习]-IDEA创建Gradle多Module结构的SpringBoot项目 RabbitMQ RabbitMQ 安装 linux安装RabbitMQ详细教程 Ubuntu 16.04 RabbitMq 安装与运行(安装篇) ubantu安装...

OSC_fly
2018/07/26
0
0
SpringMVC跨域配置以及权限控制拦截跨域请求时的问题解决

背景 最近公司开始推行前后端分离的架构,于是不可避免的引入了跨域的问题,跨域的概念可以参考大佬的博客,这里就不再赘述了。 作为Java最流行框架之一的Spring其实已经帮我们写好了很多代码...

Iceberg_XTY
2018/09/29
0
0
Shiro和SpringBoot简单集成

Shiro是一种简单的安全框架,可以用来处理系统的登录和权限问题。 本篇记录一下Spring Boot和Shiro集成,并使用Jwt Token进行无状态登录的简单例子。 参考Demo地址,此Demo适合用于SpringBoo...

萌璐琉璃
2018/09/10
0
0
SpringBoot+Redis实现token鉴权的例子

实现结果 本着结果导向的原则,先说一下这个例子最后实现的效果是啥:用户登录成功后后台会返回一个token给调用者,同时我们自定义了@AuthToken注解,被该注解标注的api进行请求的时候都需要...

vzard
2018/08/06
0
0
Public CMS V4.0.180825 发布,静态化多站点 CMS

框架升级 jdk最低要求升级到1.8 springboot升级为2.0.4 程序功能修改 后台UI升级(新UI由同创蓝宇公司义务设计制作) 增加kindeditor编辑器 增加子站点功能 增加动态页面参数加密验证url规则 ...

湖水没了
2018/08/28
1K
9

没有更多内容

加载失败,请刷新页面

加载更多

KaliLinuxNetHunter教程下载相关资源

KaliLinuxNetHunter教程下载相关资源 当用户将刷机工具准备完后,则需要下载ROM包。ROM是ROM image(只读内存镜像)的简称,常用于手机定制系统。一般手机刷机的过程,就是将只读内存镜像(R...

大学霸
15分钟前
1
0
C# 字符串插值

字符串插值 据说是 C# 6.0 中引入的新特性. 字符串插值允许您以更简洁易读的方式将字符串拼凑在一起. 如果在字符串的左引号前添加$,则可以在字符串中的大括号里包含字符串值,如变量等. 一些示...

taadis
39分钟前
2
0
Navicat使用教程:接收MySQL/MariaDB问题通知

下载Navicat Monitor最新版本 Navicat Monitor 是一套安全、简单而且无代理的远程服务器监控工具。它具有强大的功能使你的监控发挥最大效用。受监控的服务器包括 MySQL、MariaDB 和 Percona ...

电池盒
40分钟前
3
0
我是怎样和Linux系统结缘并通过红帽RHCE认证的

我高考完当时就是选择的计算机科学与技术专业,上大学以后联想到的和计算机相关的就只有写代码,开发,网站,网页设计,就没有其他的了,当时学习写代码也都是在Windows上,什么C#、C++之类的...

Linux就该这么学
48分钟前
5
0
hbase的web页面访问

hbase1.1版本web页面默认不开放 在hbase-site.xml中加入一下内容即可 <!-- 新增的配置 --><property><name>hbase.master.info.port</name><value>60010</value></property> 借鉴htt......

你为什么不吃药
52分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部