文档章节

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

f
 funnymin
发布于 10/16 06:47
字数 979
阅读 23
收藏 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学习笔记

RabbitMQ RabbitMQ 安装 linux安装RabbitMQ详细教程 Ubuntu 16.04 RabbitMq 安装与运行(安装篇) ubantu安装rabbitMQ步骤 多线程 Spring @transactional注解和synchronized同步锁同时使用不...

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

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

Iceberg_XTY
09/29
0
0
SpringBoot+Redis实现token鉴权的例子

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

vzard
08/06
0
0
Shiro和SpringBoot简单集成

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

萌璐琉璃
09/10
0
0
恒宇少年/spring-boot-chapter

简书整套文档以及源码解析 专题 专题名称 专题描述 001 Spring Boot 核心技术 讲解SpringBoot一些企业级层面的核心组件 002 Spring Cloud 核心技术 对Spring Cloud核心技术全面讲解 003 Quer...

恒宇少年
04/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

在Flutter中嵌入Native组件的解决方案

摘要: 引言 在漫长的从Native向Flutter过渡的混合工程时期,要想平滑地过渡,在Flutter中使用Native中较为完善的控件会是一个很好的选择。本文希望向大家介绍AndroidView的使用方式以及在此...

阿里云官方博客
39分钟前
1
0
aws S3 util demo

package com.example.demo;import com.amazonaws.AmazonClientException;import com.amazonaws.AmazonServiceException;import com.amazonaws.auth.BasicAWSCredentials;import co......

经常把天聊死的胖子
59分钟前
4
0
linux下查看cpu、memo、io、swap性能数据脚本

直接贴脚本: 1、cpu #!/bin/bashCurrentDate=`date -d today '+%Y%m%d'`CurrentTime=`date -d today '+%Y%m%d%H%M'`mytext="$CurrentTime\t`top -b -n 1 | grep Cpu\(s\......

郑加威
今天
5
0
MySQL之——查询重复记录、删除重复记录方法大全

MySQL之——查询重复记录、删除重复记录方法大全

安小乐
今天
2
0
spring容器启动,停止,关闭事件监听-ApplicationEvent

ApplicationEvent ApplicationEvent相当于一个事件,所有自定义事件都需要继承这个抽象类。在Eclipse中Ctrl+Shift+H调用类的层次结构列表,可以看到如下 Application下抽象子类ApplicationCo...

tantexian
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部