Spring Session - REST
本指南介绍了如何在使用 REST 端点时使用 Spring Session 将 Redis 透明地利用为 Web 应用程序的 HttpSession
提供支持。
This guide describes how to use Spring Session to transparently leverage Redis to back a web application’s HttpSession
when you use REST endpoints.
您可以在 rest sample application 中找到已完成的指南。 |
You can find the completed guide in the rest-sample. |
Updating Dependencies
在使用 Spring 会话之前,您必须更新依赖。如果您使用 Maven,您必须添加以下依赖:
Before you use Spring Session, you must update your dependencies. If you use Maven, you must add the following dependencies:
<dependencies>
<!-- ... -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>{spring-session-version}</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>{lettuce-core-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>{spring-core-version}</version>
</dependency>
</dependencies>
Spring Configuration
在添加所需的依赖项后,我们可以创建我们的 Spring 配置。Spring 配置负责创建一个 Servlet 过滤器,该过滤器将 HttpSession
实现替换为由 Spring Session 支持的实现。为此,请添加以下 Spring 配置:
After adding the required dependencies, we can create our Spring configuration.
The Spring configuration is responsible for creating a servlet filter that replaces the HttpSession
implementation with an implementation backed by Spring Session.
To do so, add the following Spring Configuration:
Unresolved include directive in modules/ROOT/pages/guides/java-rest.adoc - include::example$spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/HttpSessionConfig.java[]
1 | The @EnableRedisHttpSession annotation creates a Spring bean named springSessionRepositoryFilter that implements Filter .
The filter is in charge of replacing the HttpSession implementation to be backed by Spring Session.
In this instance, Spring Session is backed by Redis. |
2 | We create a RedisConnectionFactory that connects Spring Session to the Redis Server.
We configure the connection to connect to localhost on the default port (6379).
For more information on configuring Spring Data Redis, see the {docs-url}/spring-data/data-redis/docs/{spring-data-redis-version}/reference/html/[reference documentation]. |
3 | We customize Spring Session’s HttpSession integration to use HTTP headers to convey the current session information instead of cookies. |
Servlet Container Initialization
我们的 Spring Configuration 创建了一个名为 springSessionRepositoryFilter
的 Spring Bean,它实现了 Filter
。springSessionRepositoryFilter
Bean 负责使用由 Spring 会话支持的自定义实现来替换 HttpSession
。
Our rest-spring-configuration created a Spring Bean named springSessionRepositoryFilter
that implements Filter
.
The springSessionRepositoryFilter
bean is responsible for replacing the HttpSession
with a custom implementation that is backed by Spring Session.
为了让我们的 Filter
发挥作用,Spring 需要加载我们的 Config
类。我们在 Spring MvcInitializer
中提供配置,如下面的示例所示:
In order for our Filter
to do its magic, Spring needs to load our Config
class.
We provide the configuration in our Spring MvcInitializer
, as the following example shows:
Unresolved include directive in modules/ROOT/pages/guides/java-rest.adoc - include::example$spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/mvc/MvcInitializer.java[]
最后,我们需要确保我们的 Servlet 容器(即 Tomcat)对每个请求使用我们的 springSessionRepositoryFilter
。幸运的是,Spring 会话提供了一个名为 AbstractHttpSessionApplicationInitializer
的实用程序类,使此操作变得简单。为此,使用默认构造函数扩展该类,如下面的示例所示:
Last, we need to ensure that our Servlet Container (that is, Tomcat) uses our springSessionRepositoryFilter
for every request.
Fortunately, Spring Session provides a utility class named AbstractHttpSessionApplicationInitializer
that makes doing so easy. To do so, extend the class with the default constructor, as the following example shows:
Unresolved include directive in modules/ROOT/pages/guides/java-rest.adoc - include::example$spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/Initializer.java[]
我们的类 ( |
The name of our class ( |
rest
Sample Application
本部分介绍如何使用 rest
样本应用程序。
This section describes how to use the rest
sample application.
Running the rest
Sample Application
您可以获取 源代码 并调用以下命令运行示例:
You can run the sample by obtaining the source code and invoking the following command:
要让示例发挥作用,你必须在 localhost 上 install Redis 2.8+ 并使用默认端口 (6379) 运行它。或者,你可以更新 |
For the sample to work, you must install Redis 2.8+ on localhost and run it with the default port (6379).
Alternatively, you can update the |
$ ./gradlew :spring-session-sample-javaconfig-rest:tomcatRun
您现在应该能够访问 [role="bare"][role="bare"]http://localhost:8080/ 中的应用程序。
You should now be able to access the application at [role="bare"]http://localhost:8080/
Exploring the rest
Sample Application
你现在可以尝试使用该应用。要执行此操作,请使用你喜爱的 REST 客户端请求 [role="bare"][role="bare"]http://localhost:8080/。
You can now try to use the application. To do so, use your favorite REST client to request [role="bare"]http://localhost:8080/
$ curl -v http://localhost:8080/
请注意,系统会提示您进行基本认证。提供以下用户名和密码信息:
Note that you are prompted for basic authentication. Provide the following information for the username and password:
-
Username user
-
Password password
然后,运行以下命令:
Then run the following command:
$ curl -v http://localhost:8080/ -u user:password
在输出中,您应会看到以下内容:
In the output, you should notice the following:
HTTP/1.1 200 OK ... X-Auth-Token: 0dc1f6e1-c7f1-41ac-8ce2-32b6b3e57aa3 {"username":"user"}
具体来说,您应该注意我们响应的以下内容:
Specifically, you should notice the following things about our response:
-
The HTTP Status is now a 200.
-
We have a header a the name of
X-Auth-Token
and that contains a new session ID. -
The current username is displayed.
我们现在可以使用 X-Auth-Token
再次提出请求而无需再次提供用户名和密码。例如,如下命令输出了用户名,与之前一样:
We can now use the X-Auth-Token
to make another request without providing the username and password again. For example, the following command outputs the username, as before:
$ curl -v http://localhost:8080/ -H "X-Auth-Token: 0dc1f6e1-c7f1-41ac-8ce2-32b6b3e57aa3"
唯一的区别是会话 ID 未在响应头中提供,因为我们正在重复使用现有的会话。
The only difference is that the session ID is not provided in the response headers because we are reusing an existing session.
如果我们使会话失效,X-Auth-Token
会显示在响应中,并附带一个空值。例如,如下命令使我们的会话失效:
If we invalidate the session, the X-Auth-Token
is displayed in the response with an empty value. For example, the following command invalidates our session:
$ curl -v http://localhost:8080/logout -H "X-Auth-Token: 0dc1f6e1-c7f1-41ac-8ce2-32b6b3e57aa3"
在输出中,您可以看到 X-Auth-Token
提供了一个空 String
,表明上一个会话已失效:
You can see in the output that the X-Auth-Token
provides an empty String
indicating that the previous session was invalidated:
HTTP/1.1 204 No Content ... X-Auth-Token:
How Does It Work?
Spring Security 与 SecurityContextPersistenceFilter
中的标准 HttpSession
交互。
Spring Security interacts with the standard HttpSession
in SecurityContextPersistenceFilter
.
现在,Spring Security 正在持久保留 Redis 中的值,而非使用 Tomcat 的 HttpSession
。Spring Session 在浏览器中创建了一个名为 X-Auth-Token
的 header。该 header 包含会话的 ID。
Instead of using Tomcat’s HttpSession
, Spring Security is now persisting the values in Redis.
Spring Session creates a header named X-Auth-Token
in your browser.
That header contains the ID of your session.
如果您愿意,您可以轻松地看到会话是在 Redis 中创建的。为此,通过使用如下命令创建会话:
If you like, you can easily see that the session is created in Redis. To do so, create a session by using the following command:
$ curl -v http://localhost:8080/ -u user:password
在输出中,您应会看到以下内容:
In the output, you should notice the following:
HTTP/1.1 200 OK ... X-Auth-Token: 7e8383a4-082c-4ffe-a4bc-c40fd3363c5e {"username":"user"}
现在,您可以通过使用 redis-cli 删除会话。例如,在基于 Linux 的系统上,您可以输入:
Now you can remove the session by using redis-cli. For example, on a Linux based system, you can type:
$ redis-cli keys '*' | xargs redis-cli del
Redis 文档包含有关 installing redis-cli 的说明。 |
The Redis documentation has instructions for installing redis-cli. |
或者,您还可以删除显式密钥。为此,请将以下内容输入到您的终端中,确保将 7e8383a4-082c-4ffe-a4bc-c40fd3363c5e
替换为 SESSION
cookie 的值:
Alternatively, you can also delete the explicit key.
To do so, enter the following into your terminal, being sure to replace 7e8383a4-082c-4ffe-a4bc-c40fd3363c5e
with the value of your SESSION
cookie:
$ redis-cli del spring:session:sessions:7e8383a4-082c-4ffe-a4bc-c40fd3363c5e
现在,我们可以使用 X-Auth-Token
对我们已删除的会话发出另一个请求,并观察到我们被提示进行身份验证。例如,如下命令返回一个 HTTP 401:
We can now use the X-Auth-Token
to make another request with the session we deleted and observe we that are prompted for authentication. For example, the following returns an HTTP 401:
$ curl -v http://localhost:8080/ -H "X-Auth-Token: 0dc1f6e1-c7f1-41ac-8ce2-32b6b3e57aa3"