【问题标题】:spring security permitAll still considering token passed in Authorization header and returns 401 if token is invalidspring security permitAll 仍在考虑在 Authorization 标头中传递的令牌,如果令牌无效则返回 401
【发布时间】:2016-07-17 18:00:40
【问题描述】:

我在我的项目中使用 spring security oauth。我通过在 spring security ResourceServerConfigurerAdapter 中进行配置,从身份验证中排除了一些 url。我加了http.authorizeRequests().antMatchers(url).permitAll()

现在,我看到的是,如果我不将 Authorization 标头传递给这些 url,它就不会经过身份验证。并且 API 被正确调用。

如果使用 Authorization 标头进行调用,则它会验证令牌,如果令牌未被验证,则调用失败。

我的问题是我需要做什么才能在我拥有 permitAll 的请求中忽略令牌。

【问题讨论】:

    标签: spring authentication spring-security spring-security-oauth2


    【解决方案1】:

    Spring OAuth2 将拦截所有带有 header: Authorization Bearer xxx 的 url。

    为了避免 Spring OAuth2 拦截 url。我创建了一个比 Spring OAuth2 配置更高阶的 SecurityConfiguration。

    @Configuration
    @EnableWebSecurity
    @Order(1) // this is important to run this before Spring OAuth2 
    public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    
        @Override
        @Bean
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            List<RequestMatcher> requestMatchers = new ArrayList<RequestMatcher>();
            // allow /api/public/product/** and /api/public/content/** not intercepted by Spring OAuth2
            requestMatchers.add(new AntPathRequestMatcher("/api/public/product/**"));
            requestMatchers.add(new AntPathRequestMatcher("/api/public/content/**"));
    
        http
            .requestMatcher(new OrRequestMatcher(requestMatchers))
        .authorizeRequests()
          .antMatchers("/api/public/product/**", "/api/public/content/**").permitAll()
        }
    }
    

    以上配置允许 /api/public/product/** 和 /api/public/content/** 由该配置处理,而不是由 Spring OAuth2 处理,因为该配置具有更高的@Order。

    因此,即使将无效令牌设置为上述api调用也不会导致无效的访问令牌。

    【讨论】:

    • 但是如果token是有效的,你就无法获得认证用户。
    • @meobeo173 是的,正如你所说,我无法从 auth-server 获取 userInfo。所以,我将user-info-url 端点切换到 api-server。
    • @meobeo173 我正在使用spring-oauth2spring-boot 设置。但是我创建了 url 以在我的身份验证服务器上获取经过身份验证的用户信息 (security.oauth2.resource.user-info-uri)。在我将我的 spring-security 配置类的顺序更改为1 之前可以,正如这个答案所描述的那样。因此,我将 user-info-uri 端点移到了我的 api-server,它为来自 auth-server 应用程序的休息服务提供服务。
    【解决方案2】:

    根据 spring-oauth2 文档https://projects.spring.io/spring-security-oauth/docs/oauth2.html

    注意:如果您的授权服务器也是资源服务器,那么还有另一个具有较低优先级的安全过滤器链来控制 API 资源。对于那些受访问令牌保护的请求,您需要它们的路径不与主要面向用户的过滤器链中的路径匹配,因此请确保在上面的 WebSecurityConfigurer 中包含一个仅挑选非 API 资源的请求匹配器。

    所以定义 WebSecurityConfigurer 实现的顺序比 ResourceServerConfig 更高。

    【讨论】:

    • 你能详细解释一下粗体字吗?我的意思是,如果有另一个优先级较低的安全过滤器链,为什么它可以控制 API 资源?如果我们为非 API 资源维护一个 WebSecurityConfigurer,那么这些非 API 资源是什么? @hermantvsn
    【解决方案3】:

    如果您正在处理 Reactive Spring webflux,来自 SooCheng Koh 的回答。

    @Configuration
    @EnableWebFluxSecurity
    @EnableReactiveMethodSecurity
    @Order(1) // this is important to run this before Spring OAuth2
    public class PublicSecurityConfiguration {
    
    
        @Bean
        public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    
            http
    
                .authorizeExchange()
                .pathMatchers("/api/public/**").permitAll();
            return http.build();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-06-24
      • 2020-07-24
      • 2017-03-14
      • 2022-06-29
      • 2021-10-25
      • 2020-09-20
      • 2015-03-30
      • 2016-10-26
      • 1970-01-01
      相关资源
      最近更新 更多