Spring-Session实现SSO单点登录

简介

Spring Session 是Spring家族中的一个子项目,它提供一组API和实现,用于管理用户的session信息

它把servlet容器实现的httpSession替换为spring-session,专注于解决 session管理问题,Session信息存储在Redis中,key是由UUID生成,且以hash结构存放在redis,可简单快速且无缝的集成到我们的应用中;

Spring Session的特性:

  1. 提供用户session管理的API和实现
  2. 提供HttpSession,以中立的方式取代web容器的session,比如tomcat中的session
  3. 支持集群的session处理,不必绑定到具体的web容器去解决集群下的session共享问题

SSM中使用SpringSession

假设项目中已经配置号了redis,如若没有,请先参考ssm中集成redis

  1. maven依赖
 <dependency>
     <groupId>org.springframework.session</groupId>
     <artifactId>spring-session-data-redis</artifactId>
     <version>1.3.1.RELEASE</version>
 </dependency>
  1. 配置springSessionRepositoryFilter过滤器
 <filter>
    <filter-name>springSessionRepositoryFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

注意,放在所有过滤器之首,我是放在字符编码过滤器之后的。

  1. spring中配置spring-session
 <!--定义SpringSession的配置Bean -->
    <bean id="redisHttpSessionConfiguration" class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
        <!--指定Cookie的序列化规则对象,用于改变SpringSessionCookie的存放规则 -->
        <property name="cookieSerializer"  ref="defaultCookieSerializer"/>

 		<!--设置Session的最大生命周期,单位为秒 默认有效期为1800 表示30分钟 -->
        <!--<property name="maxInactiveIntervalInSeconds" value="1800"/>-->
    </bean>

    <!--自定义Cookie规则对象 -->
    <bean id="defaultCookieSerializer" class="org.springframework.session.web.http.DefaultCookieSerializer">
        <!--指定SpringSession的Cookie数据要存放到域名的根路径下,用于解决同域名下不同项目的Session共享 -->
        <property name="cookiePath" value="/"/>
        <!--指定SpringSession的Cookie数据要存放到根域名下,用于解决同根域名但是不同子域名的Session共享,
        低版本的Tomcat(版本小于8)如果报错要在根域名前多加个点.-->
        <property name="domainName" value="myweb.com"/>
    </bean>
  1. 定义SpringSession的配置Bean:RedisHttpSessionConfiguration

    a.指定Cookie的序列化规则对象参数
    b.设置Session的最大生命周期

  2. 自定义Cookie规则对象:DefaultCookieSerializer,这里要注意两个参数(后台区分是否是同一个session和路径和域名有关)

    a.解决同域名下不同项目的Session共享(Cookie的使用范围):设置 cookiePath 为域名的根路径
    例如:现在有两个项目,分别是:localhost:8080/web1和localhost:9090/web2,通过浏览器提供的开发人员工具(F12–>Application–>Cookies–>SESSION)可以发现,这两个请求的cookie的路径(path)不一致,一个是/web1,一个是/web2,虽然我们已经加了SpringSession共享机制,但是后台服务器认为这是两个不同的会话(session),故需要指定 cookiePath 参数为 “/”

    b.解决同根域名但是不同子域名的Session共享:设置 domainName 为要存放的根域名
    例如:还是上面的两个项目,只不过现在不再使用localhost了,而是使用域名,在C:\Windows\System32\drivers\etc\host文件中修改127.0.0.1的映射关系模拟不同的域名访问,这里使用的分别是:web1.web.com:8080/web1和web2.web.com:9090/web2,通过浏览器提供的开发人员工具可以发现,虽然这两个cookie的路径(path)都设置为了“/”,但是由于这两个cookie的域名(domain)不一致,虽然我们已经加了Spring Session共享机制,但是后台服务器同样认为这是两个不同的会话(session),故需要指定 domainName 参数为“web.com”
    注意,需要在每个项目中都加入以上步骤的配置。
    至此,SSM中配置spring-session完成!

我在项目中,实现根域名或者根路径,采用的是nginx配置,根据不同的请求,跳转到不同的项目,这样就实现了根路径一致,可以使用多个tomcat来部署不同的项目了。

SpringBoot配置Spring-Session

  1. 添加依赖
 <!--spring连接redis的起步依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--springSession的依赖-->
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
</dependency>
  1. 配置参数
#连接redis三要素:ip,端口,密码
spring.redis.host=192.168.29.128
spring.redis.port=6379
spring.redis.password=123456

#设置SessionId存放在Cookie中的什么路径中 /表示根路径,用于解决同域名下不同项目的Session共享
server.servlet.session.cookie.path=/

#设置SessionId存放在Cookie中的根域名,用于解决同根域名不同二级子域名的Session共享
server.servlet.session.cookie.domain=web.com

#设置Session的最大生命周期,默认值为30m 表示30分钟
server.servlet.session.timeout=30m

原理

  1. 页面请求被全局的过滤器org.springframework.web.filter.DelegatingFilterProxy过滤
  2. 全局的过滤器是一个代理过滤器,它不执行真正的过滤逻辑,它代理了一个Spring容器中的名为:springSessionRepositoryFilter
    的一个过滤器
  3. 代理的这个 springSessionRepositoryFilter 过滤器是从spring容器中获取的,真正执行过滤逻辑的是
    SessionRepositoryFilter
  4. 该SessionRepositoryFilter过滤器覆盖了原来servlet中的request和response接口中定义的操作session方法,替换成自己的session方法
  5. 在过滤的时候,总是会执行一个finally语句块,在finally中提交session,保存到Redis的session以hash结构存放在redis中
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值