gpt4 book ai didi

java - ReactiveSecurityContextHolder#getContext 返回一个空上下文

转载 作者:行者123 更新时间:2023-12-02 00:31:34 34 4
gpt4 key购买 nike

我尝试对用户进行身份验证(它有效)并从上下文中获取用户 token ,但它不起作用。

我有一个简单的微服务应用程序作为我的宠物项目,并使用 WebFlux 作为网络框架。我尝试调试 ReactiveSecurityContextHolder#getContext 并在 flatMap 中看到我的用户 token 在上下文中,但在我的应用程序中我有一个空上下文。

安全配置.java

@EnableWebFluxSecurity
public class SecurityConfiguration {

@Bean
public SecurityWebFilterChain securityWebFilterChain(
AuthenticationWebFilter authenticationWebFilter,
ServerHttpSecurity http) {
return http
.csrf().disable()
.httpBasic().disable()
.formLogin().disable()
.logout().disable()
.addFilterAt(authenticationWebFilter, SecurityWebFiltersOrder.AUTHENTICATION)
.authorizeExchange()
.anyExchange().authenticated()
.and()
.build();
}

@Bean
public AuthenticationWebFilter authenticationWebFilter(
SecurityTokenBasedAuthenticationManager authenticationManager,
TokenAuthenticationConverter tokenAuthenticationConverter) {
AuthenticationWebFilter authenticationWebFilter = new AuthenticationWebFilter(authenticationManager);

authenticationWebFilter.setServerAuthenticationConverter(tokenAuthenticationConverter);
authenticationWebFilter.setSecurityContextRepository(new WebSessionServerSecurityContextRepository());

return authenticationWebFilter;
}
}

ReactiveAuthenticationManager.java

@Slf4j
@Component
@AllArgsConstructor
public class SecurityTokenBasedAuthenticationManager implements ReactiveAuthenticationManager {

private final AuthWebClient authWebClient;

@Override
public Mono<Authentication> authenticate(Authentication authentication) {

return Mono.just(authentication)
.switchIfEmpty(Mono.defer(this::raiseBadCredentials))
.cast(Authorization.class)
.flatMap(this::authenticateToken)
.map(user ->
new Authorization(user, (AuthHeaders) authentication.getCredentials()));
}

private <T> Mono<T> raiseBadCredentials() {
return Mono.error(new TokenValidationException("Invalid Credentials"));
}

private Mono<User> authenticateToken(Authorization authenticationToken) {
AuthHeaders authHeaders = (AuthHeaders) authenticationToken.getCredentials();
return Optional.of(authHeaders)
.map(headers -> authWebClient.validateUserToken(authHeaders.getAuthToken(), authHeaders.getRequestId())
.doOnSuccess(user -> log
.info("Authenticated user " + user.getUsername() + ", setting security context")))
.orElseThrow(() -> new MissingHeaderException("Authorization is missing"));
}
}

SecurityUtils.java

@Slf4j
public class SecurityUtils {

public static Mono<AuthHeaders> getAuthHeaders() {
return getSecurityContext()
.map(SecurityContext::getAuthentication)
.map(Authentication::getCredentials)
.cast(AuthHeaders.class)
.doOnSuccess(authHeaders -> log.info("Auth headers: {}", authHeaders));
}

private static Mono<SecurityContext> getSecurityContext() {
return ReactiveSecurityContextHolder.getContext();
}
}

WebClient 构建

(...)
WebClient.builder()
.baseUrl(url)
.filter(loggingFilter)
.defaultHeaders(httpHeaders ->
getAuthHeaders()
.doOnNext(headers -> httpHeaders.putAll(
Map.of(
REQUEST_ID, singletonList(headers.getRequestId()),
AUTHORIZATION, singletonList(headers.getAuthToken())))))
.build()
(...)

主要问题是在我的 WebClient 的构建内部 - 我希望我将拥有带有请求 header 的完整 Web 客户端,但正如我上面所描述的 - 我在 SecurityUtils.java 中有一个空上下文

最佳答案

因此,经过调查和调试,我找到了将流合并为单个流的原因。恕我直言,这并不是这个问题的原因,但现在它可以工作了。

(...)
getAuthHeaders()
.flatMap(authHeaders -> buildWebClient(url, authHeaders)
.get()
(...)

关于java - ReactiveSecurityContextHolder#getContext 返回一个空上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58010809/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com