打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

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

背景

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 {    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130

注解配置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;      }  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

以上两种方式都可以实现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);      }  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

方式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);    }} 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

    )...

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
SpringBoot 整合 Spring Security 实现安全认证【SpringBoot系列9】
Apache Shiro实现单点登录SSO | 沐风
SpringBoot 中实现跨域的5种方式
Spring MVC防御CSRF、XSS和SQL注入攻击
JAVA Oauth 认证服务器的搭建
webservice 服务端例子+客户端例子+CXF整合spring服务端测试+生成wsdl文件 +cxf客户端代码自动生成
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服