【问题标题】:Cannot access to unsecured endpoints in Spring Boot无法访问 Spring Boot 中的不安全端点
【发布时间】:2020-05-23 16:44:50
【问题描述】:

在我的控制器中,我有两个端点,一个是安全的,一个是公共的:

@GetMapping("/public")
public String getPublic() {
    return "public";
}

@PreAuthorize("hasRole('USER')")
@GetMapping("/private")
public String getPrivate() {
    return "public";
}

安全端点仅在我登录并将具有正确角色的令牌放置在请求标头中时才起作用。但是当我想在没有令牌的情况下访问公共端点时,我总是得到状态 401 错误

访问此资源需要完全身份验证

这是我的安全配置:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

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

和授权服务器配置:

@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    private final UserDetailsService appUserDetailService;

    private final AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints
                .tokenStore(tokenStore())
                .tokenEnhancer(tokenEnhancer())
                .authenticationManager(authenticationManager)
                .userDetailsService(appUserDetailService);
    }
}

我也尝试将.authorizeRequests().anyRequest().authenticated() 更改为:.authorizeRequests().anyRequest().permitAll(),但没有任何更改。我首选的方法是使用注释处理安全性。谢谢。

【问题讨论】:

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


    【解决方案1】:

    你有两个选择,一个都可以。

    选项 1:在您的端点中,像这样更改。

    @PreAuthorize("permitAll()")  
    @GetMapping("/public")
    public String getPublic() {
        return "public";
    }
    

    然后改变你的configure(HttpSecurity http) 方法,这样做。

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

    选项 2:在您的 configure(HttpSecurity http) 方法中,只需这样做。

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

    【讨论】:

    • 感谢您的回答。我的第一次尝试失败了,我总是出错。接下来我尝试在ResourceServerConfigurerAdapter 中配置HttpSecurity,它看起来很有效,但我对此感到困惑。你能告诉我ResourceServerConfigurerAdapter 中的configure(HttpSecurity http)WebSecurityConfig 有什么区别吗?我应该使用哪一个?
    • @DenisStephanov 你可以找到这个答案,它清楚地解释了它。这是关于优先级的。 stackoverflow.com/a/28604260/5715934 。因此,如果您配置了后者,它会在过滤器链中获得更高的优先级。
    • 所以如果我理解 ResourceServerConfigurerAdapter 覆盖 WebSecurityConfig 配置由于订单和保护端点,我可以只使用资源服务器 HttpSecurity 吗?
    • @DenisStephanov 这并不完全是一个覆盖。是连锁的。如果高阶过滤器向前传递一些东西,那么低层过滤器可以访问它并执行过滤。但是,如果较高级别的人不(阻止),那么较低级别的人将不会得到它。您的第二点是正确的,这意味着资源服务器是最好的地方,如果您想隔离端点级别的授权。
    • @SupunWijerathne 如果没有第二个选项,您的第一个选项将不起作用。您应该在回答中明确说明这一点。
    【解决方案2】:

    antMatchers() 可以解决问题。我们经常使用它。最好在不同的类中有不安全的端点,并通过请求映射控制类级别的安全性。

    antMatchers("/public").permitAll()
    

    链接到 spring security api - https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/config/annotation/web/builders/HttpSecurity.html#antMatcher-java.lang.String-

    【讨论】:

      猜你喜欢
      • 2021-03-11
      • 2016-06-01
      • 2019-01-08
      • 2020-09-15
      • 2014-02-02
      • 2020-03-26
      • 2019-07-10
      • 2019-05-11
      • 1970-01-01
      相关资源
      最近更新 更多