前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Security Oauth2 permitAll()方法小记

Spring Security Oauth2 permitAll()方法小记

作者头像
java干货
发布2021-02-19 12:49:00
1.9K0
发布2021-02-19 12:49:00
举报
文章被收录于专栏:java干货

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

从此以后

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

前言

上周五有网友问道,在使用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

代码语言:javascript
复制
@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

代码语言:javascript
复制
@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,增加对制定路径的授权

代码语言:javascript
复制
 @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方法

代码语言:javascript
复制
    @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时
配置permitAllSecurityConfig时

代码下载

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018/05/21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 解决思路
  • 代码修改
    • 添加PermitAuthenticationFilter类
      • 添加PermitAllSecurityConfig配置
        • 修改MerryyouResourceServerConfig,增加对制定路径的授权
          • 修改测试类SecurityOauth2Test
            • 效果如下
              • 不配置permitAllSecurityConfig时
              • 配置permitAllSecurityConfig时
          • 代码下载
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档