Я не могу получить доступ к java.security.Principal
, аутентифицированному моей системой аутентификации CAS.serverWebExchange.getPrincipal()
всегда пусто.
Фактически это реализация DefaultServerWebExchange
:
@Override
public <T extends Principal> Mono<T> getPrincipal() {
return Mono.empty();
}
Другая реализация ServerWebExchange
is ServerWebExchangeDecorator
и его документация гласит:
Примечание: если целью использования декоратора является переопределение таких свойств, как getPrincipal()
, рассмотрите возможность использования ServerWebExchange.mutate()
.
Итак, мой первый вопрос : если это то, что я должен делать, в какой момент в моей конфигурации WebFlux Security (ниже) я должен использовать ServerWebExchange.mutate().getPrincipal()
переопределить ServerWebExchange.getPrincipal()
?
Мой второй вопрос : Как мне получить предварительно аутентифицированный нереактивный запрос принципала?
Пока что единственныйЯ нашел способ получить запрос Принципал от ServerWebExchange
использует отражение.Но, очевидно, это не то, что я должен делать.
@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) {
Principal nonReactivePrincipal = getPrincipalFromExchangeUsingReflection(serverWebExchange);
return Mono.just(new SecurityContextImpl(new CustomPreAuthenticationToken(nonReactivePrincipal.getName(), nonReactivePrincipal, AuthorityUtils.createAuthorityList("ROLE_USER") )));
}
};
}
private Principal getPrincipalFromExchangeUsingReflection(ServerWebExchange serverWebExchange) {
Principal principal = null;
try {
Field ServletServerHttpRequestField = serverWebExchange.getClass().getDeclaredField("request");
ServletServerHttpRequestField.setAccessible(true);
Object servletServerHttpRequest = ServletServerHttpRequestField.get(serverWebExchange);
Field httpServletRequestField = servletServerHttpRequest.getClass().getDeclaredField("request");
httpServletRequestField.setAccessible(true);
HttpServletRequest httpServletRequest = (HttpServletRequest) httpServletRequestField.get(servletServerHttpRequest);
principal = httpServletRequest.getUserPrincipal();
} catch (IllegalAccessException | NoSuchFieldException e) {
log.error(e.getMessage(), e);
}
return principal;
}
}
public class CustomPreAuthenticationToken extends UsernamePasswordAuthenticationToken {
public CustomPreAuthenticationToken(String key, Object principal, Collection<? extends GrantedAuthority> authorities) {
super(key, principal, authorities);
}
}