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

Posted

技术标签:

【中文标题】Spring Security 配置 anyRequest().authenticated() 未按预期工作【英文标题】:Spring Security Configuration anyRequest().authenticated() not working as expected 【发布时间】:2018-09-23 20:33:46 【问题描述】:

我对 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 令牌,检查其有效性,从中创建身份验证,并在 SecurityContextHolder 中设置身份验证。如果没有提供令牌,SecurityContextHolder.getContext().getAuthentication() 保持为空。

我的控制器如下所示:

@RestController
@RequestMapping("/reports")
@Slf4j
public class ReportController 

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


在没有令牌的情况下对端点运行 curl 请求时,我只是得到一个有效的响应:

-> curl 'localhost:8080/reports/'
[]

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

有什么想法吗?

【问题讨论】:

【参考方案1】:

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

@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();

【讨论】:

你能不能也给我的qn解释一下:***.com/questions/55894199/…

以上是关于Spring Security 配置 anyRequest().authenticated() 未按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security:如何将两个应用程序与单独的 Spring Security 配置集成?

spring-security-oauth2中的HttpSecurity配置问题

Spring Security - 多种配置 - 添加 LogoutHandler

尽管我们不提供 Spring Security 配置,为啥 Spring Security 应用程序会重定向到登录页面?

Spring + Hibernate + Spring Security 配置

Spring Security入门(2-2)Spring Security 的运行原理 2