I am using Spring boot 2.5.6 with webflux security.
@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);
final MyAppUserDetails user = (MyAppUserDetails) ((UsernamePasswordAuthenticationToken) principal) .getPrincipal();
Here I am able to retrieve the logged in user details. The MyAppUserDetails will have user details like firstName, lastName, email, user id, org id, .... Now, I would like to update the user details in session after the user is logged in, say change the user name without asking the user to logout and login.
I tried the code below, but not sure how to set the credentials and set the updated user into the security context so that the next get current user call from security context will return the updated user.
final MyAppUserDetails appUser = new MyAppUserDetails("firstName", "lastName", "email", 1, 4);
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(appUser, ....);
ReactiveSecurityContextHolder.withAuthentication(authentication);
It is working, but not sure why do we need to save the context with the approach below.
serverSecurityContextRepository.save(request.exchange(), context);
It works without the above call.