Spring Security Oauth2 permitAll()方法小記

黃鼠狼在養雞場山崖邊立了塊碑,寫道:「不勇敢地飛下去,你怎麼知道本身原來是一隻搏擊長空的鷹?!」java

今後之後git

黃鼠狼天天都能在崖底吃到那些摔死的雞!github

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

解決思路

根據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

🙂🙂🙂關注微信小程序java架構師歷程
上下班的路上無聊嗎?還在看小說、新聞嗎?不知道怎樣提升本身的技術嗎?來吧這裏有你須要的java架構文章,1.5w+的java工程師都在看,你還在等什麼?架構

相關文章
相關標籤/搜索