返回

Spring Security 中 OAuth2 资源服务器的会话管理

java

Spring Security 中的经过身份验证的会话管理

问题

在使用 Spring Security 6 的 OAuth2 资源服务器中,客户端应用程序发送带有声明的 JWT 令牌。服务器可以验证令牌,但后续请求没有携带 JWT 令牌,而是带有会话标头,且未得到授权。

原因分析

Spring Security 默认情况下不会创建会话。需要明确启用会话管理和配置会话创建策略。

解决方案

要启用会话管理,请在 HttpSecurity 配置中添加以下代码:

@Bean
public SecurityFilterChain oauth2Chain(HttpSecurity http) throws Exception {
    http
        // 持久化身份验证
        .sessionManagement(httpSecuritySessionManagementConfigurer ->
            httpSecuritySessionManagementConfigurer
                .sessionCreationPolicy(SessionCreationPolicy.IF_NEEDED))
        // 持久化上下文
        .securityContext((securityContext) -> securityContext
                .securityContextRepository(new HttpSessionSecurityContextRepository()))
        // 默认策略:对所有请求进行 jwt oauth2
        .authorizeHttpRequests(authorize -> authorize
                .anyRequest().authenticated())
        .oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults()));
    return http.build();
}

其他注意事项

  • 会话存储: Spring Security 默认将会话存储在内存中,可通过 sessionRepository() 方法配置自定义会话存储。
  • 会话 Cookie: Spring Security 默认使用名为 SESSION 的会话 Cookie,可通过 sessionManagement().sessionCookie() 更改名称。

结论

通过这些步骤,你可以正确管理 Spring Security 中经过身份验证的会话。客户端应用程序可以在每个会话中进行一次身份验证,即使不携带 JWT 令牌。

常见问题解答

  1. 为什么需要启用会话管理?
    会话管理允许 Spring Security 持久化用户身份验证,以便客户端可以在后续请求中保持登录状态。

  2. 什么情况下需要创建会话?
    会话在需要时创建,例如当客户端发送带有有效 JWT 令牌的请求时。

  3. 如何持久化安全上下文?
    通过 securityContext() 方法,使用 HttpSessionSecurityContextRepository 将安全上下文持久化到 HTTP 会话。

  4. Spring Security 使用什么类型的会话存储?
    默认情况下使用内存会话存储,但可以使用自定义存储。

  5. Spring Security 如何使用会话 Cookie?
    Spring Security 使用名为 SESSION 的会话 Cookie 存储会话 ID,默认情况下,此名称可以更改。