1. 程式人生 > >使用spring-session、redeis實現跨二級域名單點登入

使用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配置
<?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>
5、修改web.xml,加入如下片段(我的工程是基於spring mvc、再整合spring-seesion)

注意:

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/