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 Cluster
redis.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"));
}