Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用SessionCreationPolicy.STATELESS时从Spring获取当前登录用户_Spring_Spring Boot_Spring Security_Spring Security Oauth2_Spring Security Rest - Fatal编程技术网

使用SessionCreationPolicy.STATELESS时从Spring获取当前登录用户

使用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

我想使用带有SpringSecurity5的Keyclock服务器来实现这一点

我将使用OAuth2.0身份验证和JWT令牌。我感兴趣的是如何让当前登录的用户进入Rest端点

我已经使用
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());
    }
你可能想探索一下