【问题标题】:Why Spring Security permitAll() is not working with OAuth2.0?为什么 Spring Security permitAll() 不适用于 OAuth2.0?
【发布时间】:2019-04-26 07:52:15
【问题描述】:

我有一个使用 OAuth2.0 保护的 REST API 我可以使用 http://localhost:8085/auth/token?grant_type=password&username=22@gmail.com&password=mypass(连同用户名通过基本身份验证)获取访问令牌。
但是当我尝试访问 http://localhost:8085/api/v1/signup 时,API 会返回一个 401 unauthorized 错误。
虽然我使用了antMatchers("/signup").permitAll(),但为什么API 期望access-token 访问该资源?将access-token 与此请求一起传递将注册一个用户。
这是我的资源服务器配置

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

//require beans and methods here

@Autowired
public void configureGlobal(final AuthenticationManagerBuilder auth) {
    auth.authenticationProvider(authProvider());
}

@Override
public void configure(final HttpSecurity http) throws Exception {
    http
    .authorizeRequests()
    .antMatchers("/signup").permitAll()
    .anyRequest().authenticated()
    .and()
    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
    .csrf().disable();
}
}

更新:正如this 线程所建议的,我在 `` 处忽略了/signup,但这也没有用。

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
@ComponentScan(basePackages = { "com.sample.rest.security" })
@Order(2)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    //other Beans & methods

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        List<RequestMatcher> requestMatchers = new ArrayList<RequestMatcher>();
        requestMatchers.add(new AntPathRequestMatcher("/signup/**"));

        http.
        requestMatcher(new OrRequestMatcher(requestMatchers)).
        authorizeRequests().antMatchers("/signup/**")
        .permitAll();
    }

}

【问题讨论】:

    标签: java spring spring-boot spring-security spring-security-oauth2


    【解决方案1】:

    我有问题。这是导致问题的上下文路径。我有一个使用映射 URL /api/v1/* 定义的调度程序 servlet,可以看到我的 signup 请求,它包含一个上下文路径,即 http://localhost:8085/api/v1/signup

    对于 Spring 中的 OAuth2 配置,我们需要特别注意上下文路径。首先,应该在 AuthorizationServer 中定义

    @Configuration
    @EnableAuthorizationServer
    public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
      @Override
      public void configure(final AuthorizationServerEndpointsConfigurer endpoints) { 
            endpoints
            .prefix("/api/v1") //here
            .tokenStore(tokenStore())
            .accessTokenConverter(accessTokenConverter())
            .authenticationManager(authenticationManager)
            .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
      }
    

    然后,必须像这样将上下文添加到permitAll() 路径中

    @Override
    public void configure(final HttpSecurity http) throws Exception {
        http
        .authorizeRequests()
        .antMatchers("/api/v1/signup").permitAll()  //context path here
        .anyRequest().authenticated();
    }
    

    到目前为止,注册请求仍然需要传递一个访问令牌。要从注册中删除 OAuth 安全性,我们需要删除 WebSecurity 的安全性,这可以使用 WebSecurityConfigurerAdapter 来完成

    @EnableWebSecurity
    @EnableGlobalMethodSecurity
    @ComponentScan(basePackages = { "com.sample.rest.security" })
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
         @Override
         public void configure(WebSecurity webSecurity) throws Exception {
            webSecurity.ignoring().antMatchers("/signup");
         }
     //////////// OR use below method ///////////
    /*  @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.
            authorizeRequests().antMatchers("/signup/**").permitAll();
        }
    */
    }
    

    注意,在WebSecurityConfigurerAdapter 配置中添加上下文路径是没有用的。

    【讨论】:

    • 我在没有上下文的情况下遇到了类似的问题。如果我要输入configure(HttpSecurity http).antMatchers("/users/**").permitAll(),那么 GET 请求就会起作用。但是任何 POST 都需要一个令牌。当我在configure(HttpSecurity http) 下添加您建议的configure(WebSecurity webSecurity) 行时,它起作用了。为什么是这样?你有什么指点吗?
    • @idipous 我没有时间深入研究发生了什么。一旦我得到,我会更新答案。
    【解决方案2】:

    我认为顺序是问题和匹配器**。

    @Override
    public void configure(final HttpSecurity http) throws Exception {
    
     http    
       .authorizeRequests()
         .antMatchers("/signup**")
         .permitAll()
         .and()
       .authorizeRequests()
         .anyRequest()
         .authenticated()
         .and()
       .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() .csrf().disable();  
    
    }
    

    【讨论】:

    • 没有帮助。还是一样的401 unauthorized 错误。顺便说一句,/signup* 用于匹配 /signup?xyz&amp;abc=1 之类的路径,/signup/** 将匹配 /signup/user 类型的路径
    猜你喜欢
    • 2020-08-21
    • 2019-03-08
    • 1970-01-01
    • 2021-01-20
    • 2021-11-01
    • 2016-02-16
    • 2019-03-10
    • 2018-03-27
    • 2018-01-31
    相关资源
    最近更新 更多