首页 > 解决方案 > Spring webflux 安全性与后端的模拟用户

问题描述

我的 spring webflux 安全代码是,

@Bean
    public SecurityWebFilterChain securitygWebFilterChain(final ServerHttpSecurity http) {

        http.securityContextRepository(securityContextRepository);
        return http.authorizeExchange().matchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
                .pathMatchers(props.getSecurity().getIgnorePatterns()).permitAll().anyExchange().authenticated()
                .and().formLogin()
                .and().exceptionHandling()
                .authenticationEntryPoint((exchange, exception) -> Mono.error(exception))
                .accessDeniedHandler((exchange, exception) -> Mono.error(exception))
                .and().build();
    }

现在,我有下面的代码来获取登录的用户详细信息。

public Mono<AppUserDetails> getUser() {
    Mono<Principal> principalMono = ReactiveSecurityContextHolder.getContext().map(SecurityContext::getAuthentication).cast(Principal.class);
    
            principalMono.flatMap(principal -> {
                if (principal instanceof AuthenticatedUserToken) {
                    final AppUserDetails user = ((AuthenticatedUserToken<?>) principal).getUser();
                    return Mono.just(user);
                } 
    
                return Mono.error(() -> new IllegalArgumentException("Invalid access"));
            }).switchIfEmpty(Mono.defer(() -> {
                return Mono.empty();
            }));
}

我有一个创建项目的 API,项目表有审计列,就像 createdBy 用户一样。我正在使用上面的代码( getUser() 方法)来检索登录的用户并从那里获取 userId。

现在,尝试通过 postman 仅使用 userId 1 的模拟用户测试此 API,而不是使用真实用户登录,因为前端尚未准备好。

如何使用模拟用户运行 Spring Boot 应用程序并在调用 getUser() 方法时返回模拟用户 ID,以便我可以端到端测试。

标签: springspring-bootspring-securityspring-webflux

解决方案


我可以使用下面的代码来实现这一点。

为 Mock 用户创建了一个基于条件的类。

@ConditionalOnProperty(prefix = "admin.service", value = "security.mode", havingValue = "MOCK")
@EnableWebFluxSecurity
public class MockSecurityConfig {

    @Autowired
    private AppProperties appProps;

    @Bean
    public SecurityWebFilterChain securitygWebFilterChain(final ServerHttpSecurity http) {

        return http.authorizeExchange().pathMatchers("/**").permitAll().and().csrf().disable().build();
    }

    @Bean
    public AuthenticatedPrinciplaProvider mockSecurityPrincipalProvider() {
        return new MockSecurityContextPrincipleProvider(props.getSecurity().getMock());
    }

}

推荐阅读