当前位置: 代码迷 >> VC/MFC >> SpringMVC+Shiro+RedisCluster筹建session统一管理
  详细解决方案

SpringMVC+Shiro+RedisCluster筹建session统一管理

热度:171   发布时间:2016-05-02 03:36:34.0
SpringMVC+Shiro+RedisCluster搭建session统一管理

?spring-shiro.xml

<?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:aop="http://www.springframework.org/schema/aop"	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"	xmlns:util="http://www.springframework.org/schema/util"	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd">		<description>Shiro Configuration</description>    <!-- 加载配置属性文件 -->	<context:property-placeholder ignore-unresolvable="true" location="classpath*:/csairjee.properties" />		<!-- 安全认证过滤器 -->	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">		<property name="securityManager" ref="securityManager" /><!-- 	<property name="loginUrl" value="${adminPath}/login" />  		<property name="loginUrl" value="/" />    	<property name="successUrl" value="${adminPath}" />  		<property name="successUrl" value="/home/*" />		<property name="unauthorizedUrl" value="/nopermission.jsp" />		<property name="filters">            <map>                <entry key="authc" value-ref="formAuthenticationFilter"/>            </map>        </property> -->		<property name="filterChainDefinitions">			<value><!--							/static/** = anon				/**/#/home = anon				/**/uploadPic = anon				/**/uploadAvatar = anon				/userfiles/** = anon				/visitor/** = anon				/verification/** = anon				/home/** = authc				${adminPath}/login = authc				${adminPath}/logout = logout				${adminPath}/** = user-->						 	</value>		</property>	</bean>				<!-- 用户授权信息Cache, 采用EhCache -->	<bean id="shiroCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">		<property name="cacheManager" ref="cacheManager"/>	</bean>		<!-- EhCache缓存配置 begin-->	<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">		<property name="configLocation" value="classpath:cache/ehcache-local.xml" />	</bean>	<!-- EhCache缓存配置 end-->			<!-- Shiro安全接口 -->	<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">				<property name="sessionManager" ref="sessionManager" /> 		<property name="realm" ref="shiroDbRealm" />		<property name="cacheManager" ref="shiroCacheManager"></property><!-- 	<property name="rememberMeManager.cookie.name" value="rememberMe"/>    	<property name="rememberMeManager.cookie.maxAge" value="3*60"/>  -->	</bean>			<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">	    <property name="globalSessionTimeout" value="3600000"/>	    <property name="sessionDAO" ref="shiroSessionDAO"/>	    <property name="sessionValidationScheduler" ref="sessionValidationScheduler"/>	    <property name="sessionValidationSchedulerEnabled" value="true"/>	    <property name="sessionIdCookie" ref="wapsession"/>	</bean>			<!--自定义session存储容器-->	<bean id="shiroSessionDAO" class="com.csair.csmbp.web.common.shiro.session.impl.ShiroSessionDAO">        <property name="shiroSessionRepository" ref="redisShiroSessionRepository"></property>           </bean>		<!--由redis做session存储容器	<bean id="redisShiroSessionDAO" class="com.csair.csmbp.web.common.shiro.session.impl.RedisShiroSessionDAO">        <property name="shiroSessionRepository" ref="redisShiroSessionRepository"></property>        <property name="expire" value="${mvn.shiro.session.timeout}"></property>    </bean>    -->       <!-- custom shiro session listener -->    <bean id="shiroSessionListener" class="com.csair.csmbp.web.listeners.ShiroSessionListener">        <property name="shiroSessionRepository" ref="redisShiroSessionRepository"/>    </bean>        <!-- redis缓存shiro session库 -->    <bean id="redisShiroSessionRepository" class="com.csair.csmbp.web.common.shiro.session.impl.RedisShiroSessionRepository">        <property name="jedisClusterHelper" ref="jedisClusterHelper"/>        <property name="expire" value="${mvn.shiro.session.timeout}"></property>    </bean>        <!--redisCacheManager要实现org.apache.shiro.cache.CacheManager接口,让shiro使用redis的缓存    <bean id="shiroCacheManager" class="com.csair.csmbp.web.common.shiro.cache.impl.ShiroCacheManager">        <property name="customerCacheManager" ref="redisCacheManager"></property>    </bean> -->        <!-- redis缓存cache     <bean id="redisCacheManager" class="com.csair.csmbp.web.common.shiro.cache.impl.RedisCacheManager">        <property name="jedisClusterHelper" ref="jedisClusterHelper"></property>    </bean> -->        	<!--	指定本系统SESSIONID, 默认为: JSESSIONID	问题: 与SERVLET容器名冲突, 如JETTY, TOMCAT 等默认JSESSIONID,	当跳出SHIRO SERVLET时如ERROR-PAGE容器会为JSESSIONID重新分配值导致登录会话丢失!	-->	<bean id="wapsession" class="org.apache.shiro.web.servlet.SimpleCookie">	    <constructor-arg name="name" value="WAPSESSIONID"/>	</bean>	<!--	定时清理僵尸session,Shiro会启用一个后台守护线程定时执行清理操作	用户直接关闭浏览器造成的孤立会话	-->	<bean id="sessionValidationScheduler"	      class="org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler">	    <property name="interval" value="3600000"/>	    <property name="sessionManager" ref="sessionManager"/>	</bean>		<!-- 用户自定义Realm -->	<bean  id="shiroDbRealm" class="com.csair.csmbp.web.common.shiro.realm.ShiroDbRealm">	<!--  <property name="credentialsRealm" ref="customCredentialsRealm"/>  -->	</bean>			<!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->	<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>				<!-- AOP式方法级权限检查  启用shiro注解 -->	<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">		<property name="proxyTargetClass" value="true" />	</bean>		<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">    	<property name="securityManager" ref="securityManager"/>	</bean>			</beans>

?

在web.xml添加

 <filter>	    <filter-name>shiroFilter</filter-name>	    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>	    <init-param>	      <param-name>targetFilterLifecycle</param-name>	      <param-value>true</param-value>	    </init-param>	 </filter>	 <filter-mapping>	    <filter-name>shiroFilter</filter-name>	    <url-pattern>/*</url-pattern>	 </filter-mapping>

?

pom.xml中添加

<!-- SECURITY shiro begin -->		<dependency>			<groupId>org.apache.shiro</groupId>			<artifactId>shiro-core</artifactId>			<version>${shiro.version}</version>		</dependency>		<dependency>			<groupId>org.apache.shiro</groupId>			<artifactId>shiro-spring</artifactId>			<version>${shiro.version}</version>		</dependency>		<dependency>			<groupId>org.apache.shiro</groupId>			<artifactId>shiro-web</artifactId>			<version>${shiro.version}</version>		</dependency>		<dependency>			<groupId>org.apache.shiro</groupId>			<artifactId>shiro-ehcache</artifactId>			<version>${shiro.version}</version>		</dependency>		<!-- SECURITY shiro end -->-----------------------------------------------------------------------------------<mvn.redis.clusterserver>10.92.21.17:6379,10.92.21.17:7379,10.92.21.17:8379,10.92.21.18:6380,10.92.21.18:7380,10.92.21.18:8380</mvn.redis.clusterserver>

?config.properties中添加

#Redis Clusterredis.clusterserver=${mvn.redis.clusterserver}

?

在JedisClusterHelper中添加

public void flushDB(){		String[] clusterServers = this.clusterServers.split(",");		for(String clusterServer:clusterServers){			Jedis jedis = jedisCluster.getClusterNodes().get(clusterServer).getResource();						jedis.flushDB();		}	}		public Set<byte[]> keys(String pattern){		Set<byte[]> keys = null;		keys.add("begin".getBytes());		String[] clusterServers = this.clusterServers.split(",");		for(String clusterServer:clusterServers){			Jedis jedis = jedisCluster.getClusterNodes().get(clusterServer).getResource();						 boolean isBroken = false;				try{					Set<byte[]> tempKeys = jedis.keys(pattern.getBytes());					keys.addAll(tempKeys);				}catch(Exception e){		            isBroken = true;				}finally{//					returnResource(jedis, isBroken);				}					}		keys.remove("begin".getBytes());		return keys;	}

?

ShiroSessionRepository

package com.csair.csmbp.web.common.shiro.session;import org.apache.shiro.session.Session;import java.io.Serializable;import java.util.Collection;public interface ShiroSessionRepository {	 void saveSession(Session session);	 void deleteSession(Serializable sessionId);	 Session getSession(Serializable sessionId);	 Collection<Session> getAllSessions();	}

?

ShiroSessionDAO

package com.csair.csmbp.web.common.shiro.session.impl;import java.io.Serializable;import java.util.Collection;import org.apache.shiro.session.Session;import org.apache.shiro.session.UnknownSessionException;import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import com.csair.csmbp.web.common.shiro.session.ShiroSessionRepository;public class ShiroSessionDAO extends AbstractSessionDAO {		private Logger logger = LoggerFactory.getLogger(getClass());	private ShiroSessionRepository shiroSessionRepository;	public ShiroSessionRepository getShiroSessionRepository() {		return shiroSessionRepository;	}	public void setShiroSessionRepository(			ShiroSessionRepository shiroSessionRepository) {		this.shiroSessionRepository = shiroSessionRepository;	}	@Override	public void delete(Session session) {		// TODO Auto-generated method stub		  if (session == null) {	            return;	        }	        Serializable id = session.getId();	        if (id != null) {	        		        	logger.info("delete session----:"+id);	        	getShiroSessionRepository().deleteSession(id);	        }	}	@Override	public Collection<Session> getActiveSessions() {		// TODO Auto-generated method stub		return getShiroSessionRepository().getAllSessions();	}	@Override	public void update(Session session) throws UnknownSessionException {		// TODO Auto-generated method stub				logger.info("update session----更新:"+session.getId());		getShiroSessionRepository().saveSession(session);	}	@Override	protected Serializable doCreate(Session session) {		// TODO Auto-generated method stub		Serializable sessionId = this.generateSessionId(session);        this.assignSessionId(session, sessionId);        getShiroSessionRepository().saveSession(session);                logger.info("do create session----建完后:"+sessionId);        return sessionId;	}	@Override	protected Session doReadSession(Serializable sessionId) {		// TODO Auto-generated method stub		//		logger.info("do read session----参数:"+sessionId); 		return getShiroSessionRepository().getSession(sessionId);	}}

?

BaseController中添加

protected void setSessionAttribute(String key,Object obj){		Subject currentUser = SecurityUtils.getSubject();		Session session = currentUser.getSession();		session.setAttribute(key, obj);	}		protected Object getSessionAttribute(String key){		Subject currentUser = SecurityUtils.getSubject();		Session session = currentUser.getSession();		return session.getAttribute(key);	}

?

在普通的controller中调用

@RequestMapping(value = "test/setRedisSession.do")//test/zooKeeper.do?key=test	@ResponseBody	public void setSessionValue(){		setSessionAttribute("TESTSESSION", "mysession");				logger.info("TESTSESSION==========" + (String)getSessionAttribute("TESTSESSION"));	}

?

?

?

?

  相关解决方案