春季安全配置anyRequest()。authenticated()无法按预期工作

use*_*468 3 spring spring-security jwt

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

不幸的是,我的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");
    }
}
Run Code Online (Sandbox Code Playgroud)

AuthenticationTokenFilter从请求中获取JWT令牌,检查其有效性,从中创建Authentication,然后在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();
    }

}
Run Code Online (Sandbox Code Playgroud)

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

-> curl 'localhost:8080/reports/'
[]
Run Code Online (Sandbox Code Playgroud)

调试时,我看到的SecurityContextHolder.getContext().getAuthentication()为空。

有任何想法吗?

M. *_*num 5

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

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

这是您自己的配置,另外还有一些缩进。当您在antMatcher此处编写一个时,意味着后面的所有内容都antMatcher适用于在其中编写的路径/表达式(请参阅的Javadoc)AntPathMatcher

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

您可能打算写的是

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

请注意,/**而不是/*。但是,这基本上与省略antMatcher并简单地编写相同

 @Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .addFilterBefore(authenticationTokenFilter, BasicAuthenticationFilter.class)
            .authenticationProvider(tokenAuthenticationProvider)
            .authorizeRequests()
            .anyRequest().authenticated();
}
Run Code Online (Sandbox Code Playgroud)