Spring Security Oauth2 permitAll()方法小记


声明:本文转载自https://my.oschina.net/merryyou/blog/1816321,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

黄鼠狼在养鸡场山崖边立了块碑,写道:“不勇敢地飞下去,你怎么知道自己原来是一只搏击长空的鹰?!” 从此以后 黄鼠狼每天都能在崖底吃到那些摔死的鸡!

https://raw.githubusercontent.com/longfeizheng/longfeizheng.github.io/master/images/spring-security-OAuth207.png

前言

上周五有网友问道,在使用spring-security-oauth2时,虽然配置了.antMatchers("/permitAll").permitAll(),但如果在header 中 携带 Authorization Bearer xxxxOAuth2AuthenticationProcessingFilter还是会去校验Token的正确性,如果Token合法,可以正常访问,否则,请求失败。他的需求是当配置.permitAll()时,即使携带Token,也可以直接访问。

解决思路

根据Spring Security源码分析一:Spring Security认证过程得知spring-security的认证为一系列过滤器链。我们只需定义一个比OAuth2AuthenticationProcessingFilter更早的过滤器拦截指定请求,去除header中的Authorization Bearer xxxx即可。

代码修改

添加PermitAuthenticationFilter类

添加PermitAuthenticationFilter类拦截指定请求,清空header中的Authorization Bearer xxxx

@Component("permitAuthenticationFilter") @Slf4j public class PermitAuthenticationFilter extends OncePerRequestFilter {      @Override     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {          log.info("当前访问的地址:{}", request.getRequestURI());         if ("/permitAll".equals(request.getRequestURI())) {              request = new HttpServletRequestWrapper(request) {                 private Set<String> headerNameSet;                  @Override                 public Enumeration<String> getHeaderNames() {                     if (headerNameSet == null) {                         // first time this method is called, cache the wrapped request's header names:                         headerNameSet = new HashSet<>();                         Enumeration<String> wrappedHeaderNames = super.getHeaderNames();                         while (wrappedHeaderNames.hasMoreElements()) {                             String headerName = wrappedHeaderNames.nextElement();                             if (!"Authorization".equalsIgnoreCase(headerName)) {                                 headerNameSet.add(headerName);                             }                         }                     }                     return Collections.enumeration(headerNameSet);                 }                  @Override                 public Enumeration<String> getHeaders(String name) {                     if ("Authorization".equalsIgnoreCase(name)) {                         return Collections.<String>emptyEnumeration();                     }                     return super.getHeaders(name);                 }                  @Override                 public String getHeader(String name) {                     if ("Authorization".equalsIgnoreCase(name)) {                         return null;                     }                     return super.getHeader(name);                 }             };          }         filterChain.doFilter(request, response);      } }  

添加PermitAllSecurityConfig配置

添加PermitAllSecurityConfig配置用于配置PermitAuthenticationFilter

@Component("permitAllSecurityConfig") public class PermitAllSecurityConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain,HttpSecurity> {      @Autowired     private Filter permitAuthenticationFilter;      @Override     public void configure(HttpSecurity http) throws Exception {         http.addFilterBefore(permitAuthenticationFilter, OAuth2AuthenticationProcessingFilter.class);     } }  

修改MerryyouResourceServerConfig,增加对制定路径的授权

 @Override     public void configure(HttpSecurity http) throws Exception {          // @formatter:off         http.formLogin()                 .successHandler(appLoginInSuccessHandler)//登录成功处理器                 .and()                 .apply(permitAllSecurityConfig)                 .and()                 .authorizeRequests()                 .antMatchers("/user").hasRole("USER")                 .antMatchers("/forbidden").hasRole("ADMIN")                 .antMatchers("/permitAll").permitAll()                 .anyRequest().authenticated().and()                 .csrf().disable();          // @formatter:ON     } 

修改测试类SecurityOauth2Test

添加permitAllWithTokenTest方法

    @Test     public void permitAllWithTokenTest() throws Exception{         final String accessToken = obtainAccessToken();         log.info("access_token={}", accessToken);         String content = mockMvc.perform(get("/permitAll").header("Authorization", "bearer " + accessToken+"11"))                 .andExpect(status().isOk())                 .andReturn().getResponse().getContentAsString();         log.info(content);     } 
  • Authorization bearer xxx 11后面随机跟了两个参数

效果如下

不配置permitAllSecurityConfig时

https://raw.githubusercontent.com/longfeizheng/longfeizheng.github.io/master/images/security/spring-security-oauth207.gif

配置permitAllSecurityConfig时

https://raw.githubusercontent.com/longfeizheng/longfeizheng.github.io/master/images/security/spring-security-oauth208.gif

代码下载

推荐文章

  1. Java创建区块链系列
  2. Spring Security源码分析系列
  3. Spring Data Jpa 系列
  4. 【译】数据结构中关于树的一切(java版)
  5. SpringBoot+Docker+Git+Jenkins实现简易的持续集成和持续部署

https://raw.githubusercontent.com/longfeizheng/longfeizheng.github.io/master/images/wechat/xiaochengxu.png

本文发表于2018年05月22日 10:00
(c)注:本文转载自https://my.oschina.net/merryyou/blog/1816321,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2749 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1