2

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

我正在做这样的事情:

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

但是当我追踪到 authenticationManager 调用时,我发现它使用的是 Spring-Boot 的默认 InMemoryUserDetailsS​​ervice,而不是我的自定义身份验证配置。无论我是在 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" )
}
4

1 回答 1

1

没有您的测试实现很难说,但重要的是您在集成测试中运行它也许您忘记将`FilterChainProxy 添加到您的mockMvc

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

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

---在您发表评论后

这一行:

SecurityContextHolder.getContext().setAuthentication(authentication);

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

于 2015-01-20T03:50:08.470 回答