Spring Security Webflux.Как заставить ServerWebExchange вернуть принципал предварительной аутентификации - PullRequest
0 голосов
/ 04 октября 2018

Я не могу получить доступ к 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);
    }
}
...