美文网首页Spring Security
Spring Security Oauth2 permitAll

Spring Security Oauth2 permitAll

作者: 淡淡的伤你 | 来源:发表于2018-05-21 21:55 被阅读98次

    黄鼠狼在养鸡场山崖边立了块碑,写道:“不勇敢地飞下去,你怎么知道自己原来是一只搏击长空的鹰?!”

    从此以后

    黄鼠狼每天都能在崖底吃到那些摔死的鸡!

    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

    🙂🙂🙂关注微信小程序java架构师历程
    上下班的路上无聊吗?还在看小说、新闻吗?不知道怎样提高自己的技术吗?来吧这里有你需要的java架构文章,1.5w+的java工程师都在看,你还在等什么?

    相关文章

      网友评论

        本文标题:Spring Security Oauth2 permitAll

        本文链接:https://www.haomeiwen.com/subject/kefcjftx.html