java - Spring Security 5.x、WebFlux、Reactive、如何在 ReactiveSecurityContextHolder 中存储身份验证
问题描述
我正在使用 Spring Boot 2.3.1 和 WebFlux 构建 OAuth2 授权服务器。我遇到了一个问题。成功验证后,Authorization
对象中缺少该ReactiveSecurityContextHolder
对象。
我有一个实现,ServerSecurityContextRepository
它实现了load
如下方法。
@Override public Mono load(ServerWebExchange swe) {
return swe.getSession().map(WebSession::getAttributes).flatMap((attrs) -> {
ServerHttpRequest request = swe.getRequest();
String authHeader = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
if (authHeader != null && authHeader.startsWith("Bearer ") && authHeader.contains(" ")) {
// Split the auth header at space and the second token is the authToken.
String authToken = authHeader.split(" ")[1];
try {
// Some code removed here.
Authentication auth = new UsernamePasswordAuthenticationToken(principal, authToken);
SecurityContext sc = (SecurityContext)attrs.get(VarahamihirConstants.SECURITY_CONTEXT_ATTRIBUTE);
if (sc == null) {
sc = new SecurityContextImpl(auth);
save(swe, sc);
}
final SecurityContext context = sc;
return this.authenticationManager.authenticate(auth).map((authentication) -> {
context.setAuthentication(authentication);
return context;
});
} catch (ParseException|JOSEException|BadJOSEException e) {
return Mono.error(new UnauthorizedException("The auth token is invalid."));
}
} else {
return Mono.empty();
}
});
}
我还有一个实现ReactiveAuthenticationManager
which implementsauthenticate
方法。
public Mono<Authentication> authenticate(Authentication authentication) {
String authToken = authentication.getCredentials().toString();
try {
Principal principal = authentication.getPrincipal();
if (!jwtUtil.validateToken(principal.getAuthToken())) {
return Mono.empty();
}
// Some code removed.
Authentication auth = new UsernamePasswordAuthenticationToken(principal,
authToken,
actualAuthorities);
return Mono.just(auth);
})
return Mono.just(auth);
}
//SecurityContextHolder.getContext().setAuthentication(auth);
} catch (Exception e) {
e.printStackTrace();
return Mono.error(e);
}
return Mono.error(new UnauthorizedException("Unreachable place."));
}
在此之后,代码在处理身份验证流程方面工作正常,但ReactiveSecurityContextHolder
不包含任何上下文。也正因为如此,任何PrePost
注释都不能使用。
我直观地理解,我必须在某个地方将上下文保存到上下文持有者中,但是在哪里?
解决方案
推荐阅读
- css - 使用 Font Awesome 但字体不流畅
- python - Django 模型,删除集 pk
- arrays - 海量数组过滤
- postgresql - 从 postgres 表纪元时间戳开始的最后 7 天
- android - 无法解析 transaction.add(R.id.watch_video_player, youTubePlayerFragment).commit();
- c++ - 在 Makefile 的链接过程中添加库的问题
- node.js - 当我必须存储cookie olve时如何解决导致nodejs ERR_CONNECTION_RESET的Chrome cookie
- android - NDK 安装在 Unity Hub 中,但 Unity 无法访问它
- c++ - 删除“this”指针后调用函数时出现运行时错误
- javascript - 等待来自不同文件 React 的 axios 的服务器响应