专栏首页java干货Spring Security Oauth2 permitAll()方法小记

Spring Security Oauth2 permitAll()方法小记

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

从此以后

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

前言

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

配置permitAllSecurityConfig时

代码下载

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • SpringCloud微服务实战系列(十八)Ouath2在真实场景中的应用之授权服务器

    在《SpringCloud微服务实战系列(十七)Ouath2在真实场景中的应用之资源服务器》]中

    品茗IT
  • SpringCloud微服务实战系列(二十)Ouath2在真实场景中的应用之客户端接入(第二种写法)

    在《SpringCloud微服务实战系列(十七)Ouath2在真实场景中的应用之资源服务器》]中

    品茗IT
  • SpringCloud微服务实战系列(十七)Ouath2在真实场景中的应用之资源服务器

    在《SpringBoot入门建站全系列(三十五)整合Oauth2做单机版认证授权》和《Spring整合Oauth2单机版认证授权详情》中

    品茗IT
  • SpringCloud微服务实战系列(十九)Ouath2在真实场景中的应用之客户端接入(第一种写法)

    在《SpringCloud微服务实战系列(十七)Ouath2在真实场景中的应用之资源服务器》]中

    品茗IT
  • 微服务权限终极解决方案,Spring Cloud Gateway + Oauth2 实现统一认证和鉴权!

    https://github.com/macrozheng/springcloud-learning/tree/master/micro-oauth2

    macrozheng
  • spring security oauth2牛刀小试

    codecraft
  • Spring Security OAuth2实现单点登录

    在本教程中,我们将讨论如何使用 Spring Security OAuth 和 Spring Boot 实现 SSO(单点登录)。

    朝雨忆轻尘
  • 4. spring-security-oauth2 server

    主要就加了@EnableAuthorizationServer注解告诉spring启动Server模式,github登录跟上篇文章的代码一样,就是封装了一下,因...

    MasterVin
  • Spring整合Oauth2单机版认证授权详情

    OAuth 2.0 规范定义了一个授权(delegation)协议,对于使用Web的应用程序和API在网络上传递授权决策非常有用。OAuth被用在各钟各样的应用...

    品茗IT
  • spring cloud oauth2 替换用户信息

    在spring cloud 的oauth2认证中,有一个用户认证服务auth,提供客户端的认证,由于oauth2有多种授权方式,不同的授权采用的方式就不一样了。

    全栈程序员站长
  • 基于Spring Cloud Oauth2 JWT搭建微服务的安全认证中心

    Oauth协议为用户资源的授权提供了一个安全的、开放而又建议的标准。oauth的授权不会是第三方初级到用户的账号信息(如用户名与密码),及第三方无需使用用户的用...

    小东啊
  • 基于Spring Cloud 少量配置完成单点登录开发

    单点登录概念 单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登...

    冷冷
  • 【SpringSecurity系列(二十八)】当跨域遇上 Spring Security

    跨域这个问题松哥之前写过文章,但是最近收到小伙伴们的一些问题,让我发现之前的总结不够全面,因此打算再写一篇文章,来和大家分享一下 Spring Boot 中的跨...

    江南一点雨
  • Spring Boot Security OAuth2 实现支持JWT令牌的授权服务器

    之前的两篇文章,讲述了Spring Security 结合 OAuth2 、JWT 的使用,这一节要求对 OAuth2、JWT 有了解,若不清楚,先移步到下面两...

    程序员果果
  • 基于Spring Cloud 几行配置完成单点登录开发

    单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访...

    冷冷
  • spring security oauth2 password授权模式

    前面的一篇文章讲了spring security oauth2的client credentials授权模式,一般用于跟用户无关的,开放平台api认证相关的授权...

    codecraft
  • OAuth2 升级Spring Cloud Finchley.RELEASE踩坑分享

    6.19号,spring团队发布了期待已久的 Spring Cloud Finchley.RELEASE 版本。 重要变化:

    冷冷
  • OAuth2 Token 一定要放在请求头中吗?

    Token 一定要放在请求头中吗? 答案肯定是否定的,本文将从源码的角度来分享一下 spring security oauth2 的解析过程,及其扩展点的应用场...

    冷冷
  • Spring Boot + Spring Cloud 实现权限管理系统 后端篇(二十五):Spring Security 版本

    到目前为止,我们使用的权限认证框架是 Shiro,虽然 Shiro 也足够好用并且简单,但对于 Spring 官方主推的安全框架 Spring Security...

    朝雨忆轻尘

扫码关注云+社区

领取腾讯云代金券