代码之家  ›  专栏  ›  技术社区  ›  user1578872

SpringWebFlux安全性-无法检索经过身份验证的用户

  •  0
  • user1578872  · 技术社区  · 3 年前

    我正在使用带有webflux安全性的Spring boot 2.5.6。

    @EnableWebFluxSecurity
    public class AdminSecurityConfig {
              
        @Bean
        public SecurityWebFilterChain securitygWebFilterChain(final ServerHttpSecurity http,
            final ReactiveAuthenticationManager authManager,
            final ServerSecurityContextRepository securityContextRepository,
            final MyAuthenticationFailureHandler failureHandler) {
                   
            http.securityContextRepository(securityContextRepository);
    
            return http.authorizeExchange().matchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
                            .pathMatchers(props.getSecurity().getIgnorePatterns()).permitAll()
                            .pathMatchers("/api/v1/service/test").hasAuthority("DEFAULT")
                            .anyExchange().authenticated()
                            .and()
                            .formLogin()
                            .loginPage("/login")
                            .authenticationSuccessHandler(authSuccessHandler())
                            .and()
                            .exceptionHandling()
                            .authenticationEntryPoint((exchange, exception) -> Mono.error(exception))
                            .accessDeniedHandler((exchange, exception) -> Mono.error(exception))
                            .and()
                            .build();
                }
        
        @Bean
        public PasswordEncoder passwordEncoder() {
            // return new BCryptPasswordEncoder();
            return PasswordEncoderFactories.createDelegatingPasswordEncoder();
        }
        
        @Bean
        public ReactiveAuthenticationManager authenticationManager() {
            final UserDetailsRepositoryReactiveAuthenticationManager authenticationManager = new UserDetailsRepositoryReactiveAuthenticationManager(
                        userDetailsService);
            authenticationManager.setPasswordEncoder(passwordEncoder());
            return authenticationManager;
        }
        
        @Bean
        public ServerSecurityContextRepository securityContextRepository() {
            final WebSessionServerSecurityContextRepository securityContextRepository = new WebSessionServerSecurityContextRepository();
            securityContextRepository.setSpringSecurityContextAttrName("my-security-context");
            return securityContextRepository;
        }
    }
    
    Mono<Principal> principal = ReactiveSecurityContextHolder.getContext().map(SecurityContext::getAuthentication).cast(Principal.class);
    

    最终MyAppUserDetails用户=(MyAppUserDetails)((UsernamePasswordAuthenticationToken)主体) .getPrincipal();

    在这里,我可以检索登录的用户详细信息。MyAppUserDetails将包含诸如名字、姓氏、电子邮件、用户id、组织id等用户详细信息。。。。 现在,我想在用户登录后更新会话中的用户详细信息,比如更改用户名,而不要求用户注销和登录。

    我尝试了下面的代码,但不确定如何设置凭据并将更新的用户设置到安全上下文中,以便下一次从安全上下文获取当前用户调用将返回更新的用户。

    final MyAppUserDetails appUser = new MyAppUserDetails("firstName", "lastName", "email", 1, 4);
            UsernamePasswordAuthenticationToken authentication  = new UsernamePasswordAuthenticationToken(appUser, ....);
            ReactiveSecurityContextHolder.withAuthentication(authentication);
    
    0 回复  |  直到 3 年前
        1
  •  0
  •   user1578872    3 年前
    1. 从请求中获取会话。
    2. 从会话中获取上下文
    3. 创建新用户
    4. 在上下文中设置新用户
    public Mono<ServerResponse> updateSession(ServerRequest request) {
           return request.exchange().getSession().flatMap(session -> {
              final SecurityContext context = session.getAttribute("app-security-context");
              AppUserDetails newUser = AppUserDetails.of(...);
              UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(newUser, pwd, authorities);
              context.setAuthentication(token);
           }
        }
    

    它正在发挥作用,但不确定我们为什么需要用下面的方法保存上下文。

    serverSecurityContextRepository。保存(request.exchange(),context);

    它在没有上述调用的情况下工作。