2

In order to modernize a Spring MVC based application using Webflux I need to update my custom PreAuthentication scenario. I have built a good solution using FilterBeans (such as described in https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#preauth).

However, I can't find a good starting point to migrate this solution to a reactive scenario. Can anyone help me by pointing me in the right direction?

janb
  • 1,057
  • 1
  • 9
  • 11

1 Answers1

0

I am in the same situation. Trying to use container authentication (preauth.j2ee in Spring MVC) and did not find a complete solution yet.

I cannot access the java.security.Principal authenticated by my CAS authentication system. serverWebExchange.getPrincipal() is allways empty.

Since you are asking for a starting point, here is my configuration:

@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
@Slf4j
public class SecurityConfig {
@Bean
    public SecurityWebFilterChain securitygWebFilterChain(ServerHttpSecurity http) {
        return http
                .csrf().disable()
                .httpBasic().disable()
                .formLogin().disable()
                .logout().disable()

                .authenticationManager(this.authenticationManager())
                .securityContextRepository(this.securityContextRepository())
                .authorizeExchange().pathMatchers("/public/**").permitAll()
                .and().authorizeExchange().anyExchange().authenticated()
                .and().build();
    }

    @Bean
    ReactiveAuthenticationManager authenticationManager() {
        return authentication -> {
            log.debug("Autentication: " + authentication.toString());
            if (authentication instanceof CustomPreAuthenticationToken) {
                authentication.setAuthenticated(true);
            }

            return Mono.just(authentication);
        };
    }

    @Bean
    ServerSecurityContextRepository securityContextRepository() {
        return new ServerSecurityContextRepository() {
            @Override
            public Mono<Void> save(ServerWebExchange serverWebExchange, SecurityContext securityContext) {
                return null;
            }

            @Override
            public Mono<SecurityContext> load(ServerWebExchange serverWebExchange) {
                return serverWebExchange.getPrincipal()
                        .defaultIfEmpty(() -> "empty principal")
                        .flatMap(principal -> Mono.just(new SecurityContextImpl(new CustomPreAuthenticationToken(principal.getName(), principal,  AuthorityUtils.createAuthorityList("ROLE_USER") ))));
            }
        };
    }
}



public class CustomPreAuthenticationToken extends UsernamePasswordAuthenticationToken {        
    public CustomPreAuthenticationToken(String key, Object principal, Collection<? extends GrantedAuthority> authorities) {
        super(key, principal, authorities);
    }
}

Hopefully someone here can complete this answer.

Pablo
  • 1,604
  • 16
  • 31