使用 Spring 引导和 Spring 安全性对后台任务进行身份验证



我有一个后台任务(与Project Reactor一起运行,但我认为它不相关),我需要与经过身份验证的用户一起运行才能完成一些@PreAuthorize注释的方法。

我正在做这样的事情:

Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(login, password));
SecurityContextHolder.getContext().setAuthentication(authentication);

但是当我跟踪 authenticationManager 调用时,我发现它使用的是 Spring-Boot 的默认 InMemoryUserDetailsService,而不是我的自定义身份验证配置。无论我是在 Web 请求线程中还是在后台线程中运行身份验证,都会发生这种情况。

我不知道它是否相关,但我正在集成测试中运行此代码,并带有以下注释(以及其他注释):

@SpringApplicationConfiguration(classes=MyAppConfiguration.class)
@WebAppConfiguration
@IntegrationTest({"server.port:0"})

除了这个问题之外,我的测试还向我的服务器发出了经过身份验证的 Web 请求,并且身份验证很好。所以我知道至少我的系统的 Web 部分正在使用正确的身份验证配置。

这是我的身份验证配置:

@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(jsr250Enabled=true, prePostEnabled=true)
public abstract class BaseSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    public LocalUserDetailsService localUserDetailsService;
    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(localUserDetailsService);
    }
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf().disable().httpBasic()
            .and()
            .authorizeRequests()
            .antMatchers( "/admin/**" ).hasRole( "ADMIN" )
}

如果没有您的测试实现,很难分辨,但是在集成测试中运行它很重要也许你忘记了将'FilterChainProxy添加到你的mockMvc

像这样mvc = MockMvcBuilders.webAppContextSetup(context) .addFilter(springSecurityFilterChain).build();

filterChainPrioxy 的实例可以@Autowired到你的测试类中,当然这个答案可能没有意义,这取决于你对测试类的实现

---在您的评论之后

这一行:

SecurityContextHolder.getContext().setAuthentication(authentication);

将安全性约束分配给当前线程,并且不会影响在后台运行的线程,除非您的策略是全局的并且不是默认的

最新更新