原文: http://docs.spring.io/spring-session/docs/current-SNAPSHOT/reference/html5/guides/security.html
本指南介绍如何将Spring Session与Spring Security一起使用。它假定您已经应用Spring Security到您的应用程序。
完整的指导可以在这里找到。
你用Spring Session之前,你必须确保更新你的依赖。如果你正在使用Maven,确保添加以下依存关系:
文件名:pom.xml
<dependencies> <!-- ... --> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> <version>1.3.0.BUILD-SNAPSHOT</version> <type>pom</type> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.2.5.RELEASE</version> </dependency> </dependencies>
由于我们使用的是快照版本,我们需要确保添加Spring快照Maven仓库。确保你的pom.xml包含如下内容:
文件名:pom.xml
<repositories> <!-- ... --> <repository> <id>spring-snapshot</id> <url>https://repo.spring.io/libs-snapshot</url> </repository> </repositories>
添加必需的依赖关系之后,我们就可以开始创建Spring配置。Spring配置负责创建一个Spring Session实现的Servlet过滤器来取代 HttpSession
实现的过滤器。增加如下Spring配置:
@Configuration @EnableRedisHttpSession public class Config { @Bean public JedisConnectionFactory connectionFactory() { return new JedisConnectionFactory(); } }
EnableRedisHttpSession
创建了一个名为 springSessionRepositoryFilter
的Spring Bean来实现过滤器。这个由Spring Session实现的过滤器是负责替换 HttpSession
的实现。在这种情况下,Spring Session由redis支持。
然后创建了一个 RedisConnectionFactory
来连接Spring Session到地址是localhost,端口为6379的redis服务器。更多关于配置Spring Data Redis的信息可以参考 这个文档 。
上面的Spring 配置创建了一个名为 springSessionRepositoryFilter
的Spring Bean,为了让我们这个过滤器生效,Spring需要加载这个Config类。
由于我们的应用已经使用 SecurityInitializer
来加载Spring的配置,我们可以简单地把Config类加进去:
文件名:SecurityInitializer.java
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer { public SecurityInitializer() { super(SecurityConfig.class, Config.class); } }
最后我们需要确保Servlet Container(如Tomcat)为每一个请求用上我们的 springSessionRepositoryFilter
。确保Spring Session的 springSessionRepositoryFilter
在 springSecurityFilterChain
之前调用非常重要,幸运的是,Spring Session提供了一个叫做 AbstractHttpSessionApplicationInitializer
的工具类让这件事变得超级容易。你可以按下面这么写:
文件名:Initializer.java
public class Initializer extends AbstractHttpSessionApplicationInitializer { }
类的名字(Initializer)并不重要,重要的是我们继承了 AbstractHttpSessionApplicationInitializer
类
通过继承 AbstractHttpSessionApplicationInitializer
类,我们确保了 springSessionRepositoryFilter
在 springSecurityFilterChain
之前调用。
你可以获取 源码 ,输入下面的命令,来运行 Security 示例程序。
为了让示例程序正常工作,你必须安装 Redis 2.8+ 在本地(localhost),并运行在6379端口。或者,你也可以修改 JedisConnectionFactory
来指定一个Redis服务器
$ ./gradlew :samples:security:tomcatRun
现在你应该可以访问 http://localhost:8080/ 了
试着开始用这个Web应用,输入下面的用户名密码来登录:
用户名: user
密码: password
接着点击“login”按钮,你应该能够看到一个提示你已经用 user 登录的消息。用户的登录信息此时保存在Redis中而不是Tomcat所实现的 HttpSession
中。
我们实际上是在持久化登录信息到Redis中,而不是Tomcat所实现的 HttpSession
。Spring Session代替了 HttpSession
,并使用Redis来存储数据:当Spring Security的 SecurityContextPersistenceFilter
保存 SecurityContext
到 HttpSession
对象中时,他就会被持久化到Redis里。
对于Spring Security来说,当一个新的 HttpSession
被创建,Spring Session生成了一个名为SESSION的cookie发送到你的浏览器,它包含了这个Session的id。你可以到浏览器中看到这个Cookie(这里有 Chrome 和 Firefox 关于Cookie的帮助)。
如果你愿意,你可以很容易用redis-cli从Redis中删掉刚才生成的Session。比如,在一个类Linux系统中你可以这么操作:
$ redis-cli keys '*' | xargs redis-cli del
Redis的文档中有说明如何 安装redis-cli
或者,你也可以指定去删除某个key。例如输入下面的命令:
$ redis-cli del spring:session:sessions:7e8383a4-082c-4ffe-a4bc-c40fd3363c5e
现在访问 http://localhost:8080/ ,你会发现刚才的登录认证已经取消了。