使用SessionCreationPolicy.STATELESS时从Spring获取当前登录用户
我想使用带有SpringSecurity5的Keyclock服务器来实现这一点 我将使用OAuth2.0身份验证和JWT令牌。我感兴趣的是如何让当前登录的用户进入Rest端点 我已经使用使用SessionCreationPolicy.STATELESS时从Spring获取当前登录用户,spring,spring-boot,spring-security,spring-security-oauth2,spring-security-rest,Spring,Spring Boot,Spring Security,Spring Security Oauth2,Spring Security Rest,我想使用带有SpringSecurity5的Keyclock服务器来实现这一点 我将使用OAuth2.0身份验证和JWT令牌。我感兴趣的是如何让当前登录的用户进入Rest端点 我已经使用http.sessionManagement().sessionCreationPolicy(sessionCreationPolicy.STATELESS)将Spring安全配置为不存储用户会话 一种可能的方法是使用此代码: Object principal = SecurityContextHolder.ge
http.sessionManagement().sessionCreationPolicy(sessionCreationPolicy.STATELESS)将Spring安全配置为不存储用户会话代码>
一种可能的方法是使用此代码:
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof UserDetails) {
String username = ((UserDetails)principal).getUsername();
} else {
String username = principal.toString();
}
但我不知道这会不会奏效。有人能为这种情况提供一些建议吗?服务验证令牌后,您可以对其进行解析,并将其放入securitycontext中,它可以包含各种数据,因此您必须根据需要对其进行处理。例如,主题包含用户名等
SecurityContextHolder.getContext().setAuthentication(userAuthenticationObject);
SecurityContextHolder的上下文维护一个ThreadLocal条目,因此您可以在问题中编写它时在同一线程上访问它。
请注意,如果使用反应式(webflux)方法,则必须将其置于反应式上下文中。
默认情况下,SecurityContextHolder
使用ThreadLocal
存储这些详细信息,这意味着安全上下文始终可用于同一执行线程中的方法。如果在处理当前主体的请求后小心地清除线程,则以这种方式使用ThreadLocal
是非常安全的。当然,SpringSecurity会自动为您处理这些问题,因此不必担心
SessionManagementConfigurer
由isStateless()
方法组成,该方法对于无状态策略返回true。基于该http,将共享对象设置为NullSecurityContextRepository
,并将请求缓存设置为NullRequestCache
。因此,HttpSessionSecurityContextRepository
中没有可用的值。因此,对于使用静态方法的用户,可能不会出现无效/错误详细信息的问题
代码:
if (stateless) {
http.setSharedObject(SecurityContextRepository.class,
new NullSecurityContextRepository());
}
if (stateless) {
http.setSharedObject(RequestCache.class, new NullRequestCache());
}
代码:
if (stateless) {
http.setSharedObject(SecurityContextRepository.class,
new NullSecurityContextRepository());
}
if (stateless) {
http.setSharedObject(RequestCache.class, new NullRequestCache());
}
获取用户详细信息的方法
public static Optional<String> getCurrentUserLogin() {
SecurityContext securityContext = SecurityContextHolder.getContext();
return Optional.ofNullable(extractPrincipal(securityContext.getAuthentication()));
}
private static String extractPrincipal(Authentication authentication) {
if (authentication == null) {
return null;
} else if (authentication.getPrincipal() instanceof UserDetails) {
UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal();
return springSecurityUser.getUsername();
} else if (authentication.getPrincipal() instanceof String) {
return (String) authentication.getPrincipal();
}
return null;
}
public static Optional<Authentication> getAuthenticatedCurrentUser() {
log.debug("Request to get authentication for current user");
SecurityContext securityContext = SecurityContextHolder.getContext();
return Optional.ofNullable(securityContext.getAuthentication());
}
你可能想探索一下