首页 文章

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

提问于
浏览
2

我对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();
    }

}

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

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

调试时,我可以看到 SecurityContextHolder.getContext().getAuthentication() 为空 .

有任何想法吗?

1 回答

  • 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();
    }
    

相关问题