无法访问 Spring Boot 中的不安全端点

Posted

技术标签:

【中文标题】无法访问 Spring Boot 中的不安全端点【英文标题】:Cannot access to unsecured endpoints in 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(),但没有任何更改。我首选的方法是使用注释处理安全性。谢谢。

【问题讨论】:

【参考方案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 你可以找到这个答案,它清楚地解释了它。这是关于优先级的。 ***.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-

【讨论】:

以上是关于无法访问 Spring Boot 中的不安全端点的主要内容,如果未能解决你的问题,请参考以下文章

无法访问 Spring Boot Actuator“/actuator”端点

docker 镜像正在运行,但无法在 Spring Boot 应用程序中访问 REST 端点

访问 Spring Boot 指标端点的问题

Angular 无法连接到 docker compose 中的 Spring Boot 端点

Spring Boot Actuator

Spring Boot 安全配置忽略允许的端点