使用spring-session、redeis實現跨二級域名單點登入
提示:目前瞭解到的,此方式只能實現父級域名一致的子域名間單點登入,如使用者登入了a.xx.com,再訪問b.xx.com/xxx.do,則不需要再登入。
單點登入(個人理解,如有不足,請補充):由多個服務組成的一組服務,登入其中一個服務後,訪問其他服務的受限資源,不再需要登入
實現方式(個人理解,如有不足,請補充):
1、共享session:本文基於此,只有讓不同的tomcat共用一個session物件,才真正實現了session共享,從而實現單點
2、放棄session:引入認證中心,每次訪問受限資源,攜帶token
3、只是單純共享登入狀態:重寫ValveBase
,見http://blog.csdn.net/luka2008/article/details/38385703/
準備工作:
1、新建web工程(或者已經使用session的既有工程),基於maven
2、準備redis例項
3、修改pom,加入如下dependency
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.5.2</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.7.1.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> <version>1.2.0.RELEASE</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.2</version> </dependency>
4、新建spring-session.xml,寫入redis配置
5、修改web.xml,加入如下片段(我的工程是基於spring mvc、再整合spring-seesion)<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd" default-autowire="byName" default-lazy-init="true"> <!-- redis --> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> </bean> <!-- 設定Cookie domain 和 名稱 --> <bean id="defaultCookieSerializer" class="org.springframework.session.web.http.DefaultCookieSerializer"> <property name="domainName" value=".xx.com"/> <property name="cookieName" value="JSESSIONID"/> <property name="cookiePath" value="/"></property> <!-- <property name="domainNamePattern" value="^.+?\.(\w+\.[a-z]+)$"></property>--> </bean> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <property name="hostName" value="127.0.0.1" /> <property name="port" value="6379" /> <property name="poolConfig" ref="jedisPoolConfig" /> <property name="usePool" value="true" /> </bean> <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"> <property name="connectionFactory" ref="jedisConnectionFactory" /> <property name="keySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" /> </property> <property name="valueSerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" /> </property> <property name="hashKeySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" /> </property> <property name="hashValueSerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" /> </property> </bean> <!-- 將session放入redis --> <bean id="redisHttpSessionConfiguration" class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"> <property name="maxInactiveIntervalInSeconds" value="1800" /> <property name="cookieSerializer" ref="defaultCookieSerializer"/> </bean> </beans>
注意:
springSessionRepositoryFilter必須放在所有filter的最前面
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml,classpath:spring-session.xml</param-value>
</context-param>
<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>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
6、修改本地hosts檔案,將127.0.0.1分別繫結a.xx.com、b.xx.com
注意,此處的父級域名xx.com要和spring-seesion.xml中,defaultCookieSerializer的domainName屬性值配成一個,訪問時,url也要用配置的對應項訪問
情況1:domainName配成.xx.com,則驗證時,url輸入a.xx.com
情況2:domainName配成127.0.0.1,則驗證時,url輸入127.0.0.1
情況3:domainName配成localhost,則驗證時,url輸入localhost
這一點好多文章都沒有寫,這和session的建立和匹配機制有關,只有嚴格匹配了域名、path、訪問路徑才不會重複建立session,詳細瞭解參考:跨域(二級域)session共享
7、驗證
訪問a.xx.com並登入,然後訪問b.xx.com/xxx.do,則可正常訪問。
總結:
優點:對原有系統程式碼零侵入,只需修改配置,便可實現單點登入
不足:不能實現跨頂級域名(設計之初,就沒有往這個方向考慮大約)
剛開始研究沒多久,如有不妥之處,請多多拍磚。
能夠配置成功,參考瞭如下幾篇文章,多謝多謝。
Spring-session & redis 子域名共享session:http://blog.csdn.net/beflyabot/article/details/51449315
SPRING SESSION實現單點登入 :http://blog.csdn.net/moxies8090/article/details/53355244
跨域(二級域)session共享:http://blog.csdn.net/luka2008/article/details/38385703/