Common Configurations

本部分包含适用于所有或大多数 Spring Session 模块的常见配置。它包含以下使用案例的配置示例:

This section contains common configurations that applies to all or most Spring Session modules. It contains configuration examples for the following use cases:

Changing How Session IDs Are Generated

默认情况下,Spring Session 使用 UuidSessionIdGenerator,它使用 java.util.UUID 生成会话 ID。在某些情况下,包括其他字符以增加熵可能会更好,或者您可能希望使用其他算法来生成会话 ID。为此,您可以提供一个自定义 SessionIdGenerator Bean:

By default, Spring Session uses UuidSessionIdGenerator which, in turn, uses a java.util.UUID to generate a session id. There might be scenarios where it may be better to include other characters to increase entropy, or you may want to use a different algorithm to generate the session id. To change this, you can provide a custom SessionIdGenerator bean:

Changing How Session IDs Are Generated
  • Java

@Bean
public SessionIdGenerator sessionIdGenerator() {
    return new MySessionIdGenerator();
}

class MySessionIdGenerator implements SessionIdGenerator {

    @Override
    public String generate() {
        // ...
    }

}

在公开您的 SessionIdGenerator Bean 之后,Spring Session 将使用它来生成会话 ID。

After exposing your SessionIdGenerator bean, Spring Session will use it to generate session ids.

如果您正在手动配置您的 SessionRepository Bean(例如,不使用 @EnableRedisHttpSession),则可以将 SessionIdGenerator 直接设置为 SessionRepository 实现:

If you are manually configuring your SessionRepository bean (instead of using @EnableRedisHttpSession, for example), you can set the SessionIdGenerator directly on the SessionRepository implementation:

Setting SessionIdGenerator directly into SessionRepository implementation
  • Java

@Bean
public RedisSessionRepository redisSessionRepository(RedisOperations redisOperations) {
    RedisSessionRepository repository = new RedisSessionRepository(redisOperations)
    repository.setSessionIdGenerator(new MySessionIdGenerator());
    return repository;
}

设置 Spring Session 后,您可以通过公开 CookieSerializer(作为 Spring Bean)来自定义会话 Cookie 的写入方式。Spring Session 附带 DefaultCookieSerializer。当您使用诸如 @EnableRedisHttpSession 的配置时,将 DefaultCookieSerializer 作为 Spring Bean 公开会增强现有配置。以下示例显示如何自定义 Spring Session 的 Cookie:

Once you have set up Spring Session, you can customize how the session cookie is written by exposing a CookieSerializer as a Spring bean. Spring Session comes with DefaultCookieSerializer. Exposing the DefaultCookieSerializer as a Spring bean augments the existing configuration when you use configurations like @EnableRedisHttpSession. The following example shows how to customize Spring Session’s cookie:

Unresolved include directive in modules/ROOT/pages/configuration/common.adoc - include::example$spring-session-samples/spring-session-sample-javaconfig-custom-cookie/src/main/java/sample/Config.java[]
1 We customize the name of the cookie to be JSESSIONID.
2 We customize the path of the cookie to be / (rather than the default of the context root).
3 We customize the domain name pattern (a regular expression) to be ^.?\\.(\\w\\.[a-z]+)$. This allows sharing a session across domains and applications. If the regular expression does not match, no domain is set and the existing domain is used. If the regular expression matches, the first grouping is used as the domain. This means that a request to [role="bare"]https://child.example.com sets the domain to example.com. However, a request to [role="bare"]http://localhost:8080/ or [role="bare"]https://192.168.1.100:8080/ leaves the cookie unset and, thus, still works in development without any changes being necessary for production.

你应当只匹配有效的域名字符,因为域名会反映在响应中。这样做可以防止恶意用户实施攻击,比如 HTTP Response Splitting

You should only match on valid domain characters, since the domain name is reflected in the response. Doing so prevents a malicious user from performing such attacks as HTTP Response Splitting.

以下配置选项可供使用:

The following configuration options are available:

  • cookieName: The name of the cookie to use. Default: SESSION.

  • useSecureCookie: Specifies whether a secure cookie should be used. Default: Use the value of HttpServletRequest.isSecure() at the time of creation.

  • cookiePath: The path of the cookie. Default: The context root.

  • cookieMaxAge: Specifies the max age of the cookie to be set at the time the session is created. Default: -1, which indicates the cookie should be removed when the browser is closed.

  • jvmRoute: Specifies a suffix to be appended to the session ID and included in the cookie. Used to identify which JVM to route to for session affinity. With some implementations (that is, Redis) this option provides no performance benefit. However, it can help with tracing logs of a particular user.

  • domainName: Allows specifying a specific domain name to be used for the cookie. This option is simple to understand but often requires a different configuration between development and production environments. See domainNamePattern as an alternative.

  • domainNamePattern: A case-insensitive pattern used to extract the domain name from the HttpServletRequest#getServerName(). The pattern should provide a single grouping that is used to extract the value of the cookie domain. If the regular expression does not match, no domain is set and the existing domain is used. If the regular expression matches, the first grouping is used as the domain.

  • sameSite: The value for the SameSite cookie directive. To disable the serialization of the SameSite cookie directive, you may set this value to null. Default: Lax

  • rememberMeRequestAttribute: The request attribute name that indicates remember-me login. If specified, the cookie will be written as Integer.MAX_VALUE.

如果您正在使用 SpringSessionRememberMeServices 并声明一个自定义 DefaultCookieSerializer Bean,则应设置 rememberMeRequestAttribute 字段,以确保 Spring Session 依赖于会话过期而不是 Cookie 过期。为此,您可以使用以下代码片段:defaultCookieSerializer.setRememberMeRequestAttribute(SpringSessionRememberMeServices.REMEMBER_ME_LOGIN_ATTR);

If you are using SpringSessionRememberMeServices and you are declaring a custom DefaultCookieSerializer bean, you should set the rememberMeRequestAttribute field to ensure that Spring Session relies on session expiration rather than cookie expiration. To do so, you can use the following code snippet: defaultCookieSerializer.setRememberMeRequestAttribute(SpringSessionRememberMeServices.REMEMBER_ME_LOGIN_ATTR);

您可以通过将 WebSessionIdResolver 作为 Spring Bean 公开,在 WebFlux 应用程序中自定义会话 Cookie 的写入方式。Spring Session 默认使用 CookieWebSessionIdResolver。以下示例显示如何自定义 Spring Session 的 Cookie:

You can customize how the session cookie is written in a WebFlux application by exposing a WebSessionIdResolver as a Spring bean. Spring Session uses a CookieWebSessionIdResolver by default. The following example shows how to customize Spring Session’s cookie:

Unresolved include directive in modules/ROOT/pages/configuration/common.adoc - include::example$spring-session-samples/spring-session-sample-boot-webflux-custom-cookie/src/main/java/sample/CookieConfig.java[]
1 We customize the name of the cookie to be JSESSIONID.
2 We customize the path of the cookie to be / (rather than the default of the context root).
3 We customize the SameSite cookie directive to be Strict.

Providing a Spring Session implementation of ReactiveSessionRegistry

Spring Session 提供与 Spring Security 的集成,以支持其响应式并发会话控制。这允许限制单个用户同时可以拥有的活动会话的数量,但是,与默认 Spring Security 支持不同,它还可以群集环境中运行。这通过提供 Spring Security 的 ReactiveSessionRegistry 接口的 SpringSessionBackedReactiveSessionRegistry 实现来完成。

Spring Session provides integration with Spring Security to support its reactive concurrent session control. This allows limiting the number of active sessions that a single user can have concurrently, but, unlike the default Spring Security support, this also works in a clustered environment. This is done by providing the SpringSessionBackedReactiveSessionRegistry implementation of Spring Security’s ReactiveSessionRegistry interface.

Defining SpringSessionBackedReactiveSessionRegistry as a bean
  • Java

@Bean
public <S extends Session> SpringSessionBackedReactiveSessionRegistry<S> sessionRegistry(
        ReactiveSessionRepository<S> sessionRepository,
        ReactiveFindByIndexNameSessionRepository<S> indexedSessionRepository) {
    return new SpringSessionBackedReactiveSessionRegistry<>(sessionRepository, indexedSessionRepository);
}

有关使用 ReactiveSessionRegistry 的更多方法,请参阅 {spring-security-ref-docs}/reactive/authentication/concurrent-sessions-control.html[Spring Security 并发会话控制文档]。您还可以查看示例应用程序 here

Please, refer to {spring-security-ref-docs}/reactive/authentication/concurrent-sessions-control.html[Spring Security Concurrent Sessions Control documentation] for more ways of using the ReactiveSessionRegistry. You can also check a sample application here.