Spring 安全配置 anyRequest().authenticated() 未按预期工作

标签 spring spring-security jwt

我对spring security配置的理解http.anyRequest().authenticated()是任何请求都必须经过身份验证,否则我的 Spring 应用程序将返回 401 响应。

不幸的是,我的 spring 应用程序不会以这种方式运行,而是允许未经身份验证的请求通过。

这是我的 Spring 安全配置:

@Configuration
@Order(1)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private AuthenticationTokenFilter authenticationTokenFilter;

    @Autowired
    private TokenAuthenticationProvider tokenAuthenticationProvider;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .addFilterBefore(authenticationTokenFilter, BasicAuthenticationFilter.class)
                .antMatcher("/*")
                .authenticationProvider(tokenAuthenticationProvider)
                .authorizeRequests()
                .anyRequest().authenticated();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring()
                .antMatchers("/index.html")
                .antMatchers("/error")
                .antMatchers("/swagger-ui.html")
                .antMatchers("/swagger-resources");
    }
}

AuthenticationTokenFilter 从请求中获取 JWT token ,检查其有效性,从中创建身份验证,并在 SecurityContextHolder 中设置身份验证。如果未提供 token ,则 SecurityContextHolder.getContext().getAuthentication() 保持为 null。

我的 Controller 看起来像这样:
@RestController
@RequestMapping("/reports")
@Slf4j
public class ReportController {

    @RequestMapping()
    @ResponseBody
    public List<String> getIds() {
        log.info(SecurityContextHolder.getContext().getAuthentication());
        return Collections.emptyList();
    }

}

在没有 token 的情况下对端点运行 curl 请求时,我只会得到一个有效的响应:
-> curl 'localhost:8080/reports/'
[]

调试的时候可以看到SecurityContextHolder.getContext().getAuthentication()一片空白。

有任何想法吗?

最佳答案

它实际上按预期工作,这是由于您编写配置的方式。

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .addFilterBefore(authenticationTokenFilter, BasicAuthenticationFilter.class)
            .antMatcher("/*")
                .authenticationProvider(tokenAuthenticationProvider)
                .authorizeRequests()
                .anyRequest().authenticated();
}

这是你自己的配置,我有一些额外的缩进。当你写一个 antMatcher这里的意思是后面的所有内容 antMatcher适用于写在那里的路径/表达式(参见 AntPathMatcher 的 Javadoc。

现在正如您所写/*这适用于 /reports它不适用于 /reports/ (是的,最后 / 很重要!)。

你可能打算写的是
 @Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .addFilterBefore(authenticationTokenFilter, BasicAuthenticationFilter.class)
            .antMatcher("/**")
                .authenticationProvider(tokenAuthenticationProvider)
                .authorizeRequests()
                .anyRequest().authenticated();
}

注意 /**而不是 /* .然而,这基本上与省略 antMatcher 相同。并简单地写
 @Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .addFilterBefore(authenticationTokenFilter, BasicAuthenticationFilter.class)
            .authenticationProvider(tokenAuthenticationProvider)
            .authorizeRequests()
            .anyRequest().authenticated();
}

关于Spring 安全配置 anyRequest().authenticated() 未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49817729/

相关文章:

java - Spring Data 自定义实现 : Entity Not Managed

java - 无法将 Spring Security BASIC 身份验证集成到 Jersey/JAX-RS 和 Tomcat 中

jwt - Google Action 推送通知请求上的 403

error-handling - 在Angular 8中更改 token 后重新发送未经授权的请求

spring - 通过 spring 注释进行的交易 - 只读与否?

spring - 使用 Spring MVC 将 JRebel 与自定义 Ant/Ivy/Tomcat Web 应用程序集成

java - Spring、Hibernate、MVC 错误

spring - 使用 Spring Security 内存中身份验证进行内部化

java - Spring Security 和 Web MVC : How to save data that belong to a user?

java - 为什么 JSON Web Token (JWT) 在不知道 key 的情况下解密