登陆时2个tomcat打印的sessionid是一样的,可是redis没有。跟踪了一下代码刚开始进入doReadSession方法查询redis无数据后就报错了 org.apache.shiro.session.UnknownSessionException: There is no session with id【xxxxx】然后跳转到doCreate方法生成新的sessionid。就登陆不了 不知道哪里出错了。
我的配置
applicationContext-shiro.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd" default-lazy-init="false"> <!-- 用户服务接口 --> <!-- web.xml中shiro的filter对应的bean --> <!-- Shiro 的Web过滤器 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager" /> <!-- loginUrl认证提交地址,如果没有认证将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 --> <property name="loginUrl" value="/login.do" /> <!-- 认证成功统一跳转到first.action,建议不配置,shiro认证成功自动到上一个请求路径 --> <property name="successUrl" value="/successLogin.do"/> <!-- 通过unauthorizedUrl指定没有权限操作时跳转页面--> <property name="unauthorizedUrl" value="/refuse.do" /> <!-- 过虑器链定义,从上向下顺序执行,一般将/**放在最下边 --> <property name="filterChainDefinitions"> <value> /**/images/** = anon /**/script/** = anon /**/style/** = anon /logins.do = anon <!-- 请求 logout.action地址,shiro去清除session /logout.do = logout --> <!-- /** = authc 所有url都必须认证通过才可以访问 query delete update add--> /** = authc <!-- /** = anon所有url都可以匿名访问 --> </value> </property> </bean> <!-- securityManager安全管理器 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="customRealm" /> <!-- 注入session管理器 --> <property name="sessionManager" ref="sessionManager" /> <!-- cacheManager --> <property name="cacheManager" ref="cacheManager" /> </bean> <!-- realm --> <bean id="customRealm" class="com.zefu.portal.login.controller.CustomRealm"> <!-- 将凭证匹配器设置到realm中,realm按照凭证匹配器的要求进行散列 --> <property name="userService" ref="userService"/> <property name="credentialsMatcher" ref="credentialsMatcher"/> </bean> <!-- 凭证匹配器 --> <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <property name="hashAlgorithmName" value="md5" /> <property name="hashIterations" value="1" /> </bean> <!-- 缓存管理器 --> <bean id="eacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> <property name="cacheManagerConfigFile" value="classpath:shiro-ehcache.xml"/> </bean> <!-- 会话管理器 --> <!-- <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> 删除失效的session <property name="deleteInvalidSessions" value="true"/> session的失效时长,单位毫秒 3600000ms 一小时 <property name="globalSessionTimeout" value="3600000"/> 相隔多久检查一次session的有效性 <property name="sessionValidationInterval" value="1800000" /> <property name="sessionValidationSchedulerEnabled" value="true" /> </bean> --> <!-- Shiro生命周期处理器--> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> <!-- shiro redisManager --> <bean id="redisManager" class="com.zefu.portal.login.controller.RedisManager"> <property name="host" value="192.168.0.31"/> <property name="port" value="6379"/> <property name="expire" value="1800"/> <!-- optional properties: <property name="timeout" value="10000"/> <property name="password" value="123456"/> --> </bean> <!-- 会话DAO --> <bean id="redisSessionDAO" class="com.zefu.portal.login.controller.RedisSessionDAO"> <property name="redisManager" ref="redisManager" /> </bean> <!-- 会话管理器 --> <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> <property name="sessionDAO" ref="redisSessionDAO" /> <property name="globalSessionTimeout" value="1800000" /> <property name="deleteInvalidSessions" value="true" /> <property name="sessionValidationSchedulerEnabled" value="false" /> </bean> <!-- 缓存管理器 --> <bean id="cacheManager" class="com.zefu.portal.login.controller.RedisCacheManager"> <property name="redisManager" ref="redisManager" /> </bean> </beans>
package com.zefu.portal.login.controller; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apache.shiro.cache.Cache; import org.apache.shiro.cache.CacheException; import org.apache.shiro.util.CollectionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class RedisCache<K, V> implements Cache<K, V> { private Logger logger = LoggerFactory.getLogger(this.getClass()); /** * The wrapped Jedis instance. */ private RedisManager cache; /** * The Redis key prefix for the sessions */ private String keyPrefix = "shiro_redis_session:"; /** * Returns the Redis session keys * prefix. * @return The prefix */ public String getKeyPrefix() { return keyPrefix; } /** * Sets the Redis sessions key * prefix. * @param keyPrefix The prefix */ public void setKeyPrefix(String keyPrefix) { this.keyPrefix = keyPrefix; } /** * 通过一个JedisManager实例构造RedisCache */ public RedisCache(RedisManager cache){ if (cache == null) { throw new IllegalArgumentException("Cache argument cannot be null."); } this.cache = cache; } /** * Constructs a cache instance with the specified * Redis manager and using a custom key prefix. * @param cache The cache manager instance * @param prefix The Redis key prefix */ public RedisCache(RedisManager cache, String prefix){ this( cache ); // set the prefix this.keyPrefix = prefix; } /** * 获得byte[]型的key * @param key * @return */ private byte[] getByteKey(K key){ if(key instanceof String){ String preKey = this.keyPrefix + key; return preKey.getBytes(); }else{ return SerializeUtils.serialize(key); } } @Override public V get(K key) throws CacheException { logger.debug("根据key从Redis中获取对象 key [" + key + "]"); try { if (key == null) { return null; }else{ byte[] rawValue = cache.get(getByteKey(key)); @SuppressWarnings("unchecked") V value = (V)SerializeUtils.deserialize(rawValue); return value; } } catch (Throwable t) { throw new CacheException(t); } } @Override public V put(K key, V value) throws CacheException { logger.debug("根据key从存储 key [" + key + "]"); try { cache.set(getByteKey(key), SerializeUtils.serialize(value)); return value; } catch (Throwable t) { throw new CacheException(t); } } @Override public V remove(K key) throws CacheException { logger.debug("从redis中删除 key [" + key + "]"); try { V previous = get(key); cache.del(getByteKey(key)); return previous; } catch (Throwable t) { throw new CacheException(t); } } @Override public void clear() throws CacheException { logger.debug("从redis中删除所有元素"); try { cache.flushDB(); } catch (Throwable t) { throw new CacheException(t); } } @Override public int size() { try { Long longSize = new Long(cache.dbSize()); return longSize.intValue(); } catch (Throwable t) { throw new CacheException(t); } } @SuppressWarnings("unchecked") @Override public Set<K> keys() { try { Set<byte[]> keys = cache.keys(this.keyPrefix + "*"); if (CollectionUtils.isEmpty(keys)) { return Collections.emptySet(); }else{ Set<K> newKeys = new HashSet<K>(); for(byte[] key:keys){ newKeys.add((K)key); } return newKeys; } } catch (Throwable t) { throw new CacheException(t); } } @Override public Collection<V> values() { try { Set<byte[]> keys = cache.keys(this.keyPrefix + "*"); if (!CollectionUtils.isEmpty(keys)) { List<V> values = new ArrayList<V>(keys.size()); for (byte[] key : keys) { @SuppressWarnings("unchecked") V value = get((K)key); if (value != null) { values.add(value); } } return Collections.unmodifiableList(values); } else { return Collections.emptyList(); } } catch (Throwable t) { throw new CacheException(t); } } }
RedisCacheManager
package com.zefu.portal.login.controller; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.apache.shiro.cache.Cache; import org.apache.shiro.cache.CacheException; import org.apache.shiro.cache.CacheManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class RedisCacheManager implements CacheManager { private static final Logger logger = LoggerFactory .getLogger(RedisCacheManager.class); // fast lookup by name map private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap<String, Cache>(); private RedisManager redisManager; /** * The Redis key prefix for caches */ private String keyPrefix = "shiro_redis_cache:"; /** * Returns the Redis session keys * prefix. * @return The prefix */ public String getKeyPrefix() { return keyPrefix; } /** * Sets the Redis sessions key * prefix. * @param keyPrefix The prefix */ public void setKeyPrefix(String keyPrefix) { this.keyPrefix = keyPrefix; } @Override public <K, V> Cache<K, V> getCache(String name) throws CacheException { logger.debug("获取名称为: " + name + " 的RedisCache实例"); Cache c = caches.get(name); if (c == null) { // initialize the Redis manager instance redisManager.init(); // create a new cache instance c = new RedisCache<K, V>(redisManager, keyPrefix); // add it to the cache collection caches.put(name, c); } return c; } public RedisManager getRedisManager() { return redisManager; } public void setRedisManager(RedisManager redisManager) { this.redisManager = redisManager; } }
package com.zefu.portal.login.controller; import java.util.Set; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; public class RedisManager { private String host = "127.0.0.1"; private int port = 6379; // 0 - never expire private int expire = 0; //timeout for jedis try to connect to redis server, not expire time! In milliseconds private int timeout = 0; private String password = ""; private static JedisPool jedisPool = null; public RedisManager(){ } /** * 初始化方法 */ public void init(){ if(jedisPool == null){ if(password != null && !"".equals(password)){ jedisPool = new JedisPool(new JedisPoolConfig(), host, port, timeout, password); }else if(timeout != 0){ jedisPool = new JedisPool(new JedisPoolConfig(), host, port,timeout); }else{ jedisPool = new JedisPool(new JedisPoolConfig(), host, port); } } } /** * get value from redis * @param key * @return */ public byte[] get(byte[] key){ byte[] value = null; Jedis jedis = jedisPool.getResource(); try{ value = jedis.get(key); }finally{ jedisPool.returnResource(jedis); } return value; } /** * set * @param key * @param value * @return */ public byte[] set(byte[] key,byte[] value){ Jedis jedis = jedisPool.getResource(); try{ jedis.set(key,value); if(this.expire != 0){ jedis.expire(key, this.expire); } }finally{ jedisPool.returnResource(jedis); } return value; } /** * set * @param key * @param value * @param expire * @return */ public byte[] set(byte[] key,byte[] value,int expire){ Jedis jedis = jedisPool.getResource(); try{ jedis.set(key,value); if(expire != 0){ jedis.expire(key, expire); } }finally{ jedisPool.returnResource(jedis); } return value; } /** * del * @param key */ public void del(byte[] key){ Jedis jedis = jedisPool.getResource(); try{ jedis.del(key); }finally{ jedisPool.returnResource(jedis); } } /** * flush */ public void flushDB(){ Jedis jedis = jedisPool.getResource(); try{ jedis.flushDB(); }finally{ jedisPool.returnResource(jedis); } } /** * size */ public Long dbSize(){ Long dbSize = 0L; Jedis jedis = jedisPool.getResource(); try{ dbSize = jedis.dbSize(); }finally{ jedisPool.returnResource(jedis); } return dbSize; } /** * keys * @param regex * @return */ public Set<byte[]> keys(String pattern){ Set<byte[]> keys = null; Jedis jedis = jedisPool.getResource(); try{ keys = jedis.keys(pattern.getBytes()); }finally{ jedisPool.returnResource(jedis); } return keys; } public String getHost() { return host; } public void setHost(String host) { this.host = host; } public int getPort() { return port; } public void setPort(int port) { this.port = port; } public int getExpire() { return expire; } public void setExpire(int expire) { this.expire = expire; } public int getTimeout() { return timeout; } public void setTimeout(int timeout) { this.timeout = timeout; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
package com.zefu.portal.login.controller; import java.io.Serializable; import java.util.Collection; import java.util.HashSet; import java.util.Set; 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; public class RedisSessionDAO extends AbstractSessionDAO { private static Logger logger = LoggerFactory.getLogger(RedisSessionDAO.class); /** * shiro-redis的session对象前缀 */ private RedisManager redisManager; /** * The Redis key prefix for the sessions */ private String keyPrefix = "shiro_redis_session:"; @Override public void update(Session session) throws UnknownSessionException { this.saveSession(session); } /** * save session * @param session * @throws UnknownSessionException */ private void saveSession(Session session) throws UnknownSessionException{ if(session == null || session.getId() == null){ logger.error("session or session id is null"); return; } byte[] key = getByteKey(session.getId()); byte[] value = SerializeUtils.serialize(session); session.setTimeout(redisManager.getExpire()*1000); this.redisManager.set(key, value, redisManager.getExpire()); } @Override public void delete(Session session) { if(session == null || session.getId() == null){ logger.error("session or session id is null"); return; } redisManager.del(this.getByteKey(session.getId())); System.out.println("redisManager======delete:"+session.getId()+"=================="); } @Override public Collection<Session> getActiveSessions() { Set<Session> sessions = new HashSet<Session>(); Set<byte[]> keys = redisManager.keys(this.keyPrefix + "*"); if(keys != null && keys.size()>0){ for(byte[] key:keys){ Session s = (Session)SerializeUtils.deserialize(redisManager.get(key)); sessions.add(s); } } return sessions; } @Override protected Serializable doCreate(Session session) { Serializable sessionId = this.generateSessionId(session); this.assignSessionId(session, sessionId); this.saveSession(session); return sessionId; } @Override protected Session doReadSession(Serializable sessionId) { if(sessionId == null){ logger.error("session id is null"); return null; } Session s = (Session)SerializeUtils.deserialize(redisManager.get(this.getByteKey(sessionId))); return s; } /** * 获得byte[]型的key * @param key * @return */ private byte[] getByteKey(Serializable sessionId){ String preKey = this.keyPrefix + sessionId; return preKey.getBytes(); } public RedisManager getRedisManager() { return redisManager; } public void setRedisManager(RedisManager redisManager) { this.redisManager = redisManager; /** * 初始化redisManager */ this.redisManager.init(); } /** * Returns the Redis session keys * prefix. * @return The prefix */ public String getKeyPrefix() { return keyPrefix; } /** * Sets the Redis sessions key * prefix. * @param keyPrefix The prefix */ public void setKeyPrefix(String keyPrefix) { this.keyPrefix = keyPrefix; } }
package com.zefu.portal.login.controller; import java.util.ArrayList; import java.util.List; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authc.UnknownAccountException; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.util.ByteSource; import com.zefu.portal.bean.system.Permission; import com.zefu.portal.bean.system.User; import com.zefu.portal.services.menu.MenuService; import com.zefu.portal.services.permission.UserService; public class CustomRealm extends AuthorizingRealm { private UserService userService; private MenuService menuService; // 设置realm的名称 @Override public void setName(String name) { super.setName("customRealm"); } //realm的认证方法,从数据库查询用户信息 @Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token) throws AuthenticationException { // token是用户输入的用户名和密码 // 第一步从token中取出用户名 String name = (String) token.getPrincipal(); // 第二步:根据用户输入的userCode从数据库查询 User sysUser = null; try { sysUser = userService.findUserInfo(name); } catch (Exception e1) { e1.printStackTrace(); } // 如果查询不到返回null if(sysUser==null){ throw new UnknownAccountException(); } // 从数据库查询到密码 String password = sysUser.getPassword(); //盐 String salt = sysUser.getUsername(); //将activeUser设置simpleAuthenticationInfo SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo( sysUser, password, ByteSource.Util.bytes(salt),this.getName()); return simpleAuthenticationInfo; } // 用于授权 @Override protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals) { //从 principals获取主身份信息 //将getPrimaryPrincipal方法返回值转为真实身份类型(在上边的doGetAuthenticationInfo认证通过填充到SimpleAuthenticationInfo中身份类型), User user = (User) principals.getPrimaryPrincipal(); //根据身份信息获取权限信息 //从数据库获取到权限数据 List<Permission> permissionList = null; try { permissionList = userService.getPermissions(user.getRole().getRoleId()); } catch (Exception e) { e.printStackTrace(); } //单独定一个集合对象 List<String> permissions = new ArrayList<String>(); if(permissionList!=null){ for(Permission sysPermission:permissionList){ if(sysPermission!=null){ //将数据库中的权限标签 符放入集合 permissions.add(sysPermission.getElementId()); } } } //查到权限数据,返回授权信息(要包括 上边的permissions) SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); //将上边查询到授权信息填充到simpleAuthorizationInfo对象中 simpleAuthorizationInfo.addStringPermissions(permissions); return simpleAuthorizationInfo; } //清除缓存 public void clearCached() { PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals(); super.clearCache(principals); } public UserService getUserService() { return userService; } public void setUserService(UserService userService) { this.userService = userService; } public MenuService getMenuService() { return menuService; } public void setMenuService(MenuService menuService) { this.menuService = menuService; } }
package com.zefu.portal.login.controller; import java.net.InetAddress; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.DisabledAccountException; import org.apache.shiro.authc.ExcessiveAttemptsException; import org.apache.shiro.authc.ExpiredCredentialsException; import org.apache.shiro.authc.LockedAccountException; import org.apache.shiro.authc.UnknownAccountException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.authz.UnauthorizedException; import org.apache.shiro.session.Session; import org.apache.shiro.subject.Subject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import com.zefu.portal.annotation.SystemControllerLog; import com.zefu.portal.bean.system.Menu; import com.zefu.portal.bean.system.User; import com.zefu.portal.services.menu.MenuService; import com.zefu.portal.services.permission.RoleService; import com.zefu.portal.util.StringUtils; /** * 登入控制器 */ @Controller @RequestMapping("/") public class LoginController { @Autowired private MenuService menuService; @Autowired private RoleService roleService; @RequestMapping(value = "login") public String LogginGet() { return "/login/login.jsp"; } @RequestMapping("logins") public String login(User user, ModelMap map, HttpServletRequest request,HttpServletResponse httpresponse) { // 根据shiro返回的异常类路径判断,抛出指定异常信息 String msg = ""; Subject subject = SecurityUtils.getSubject(); String name=user.getUsername(); String password=user.getPassword(); UsernamePasswordToken token = new UsernamePasswordToken(name, password); if(StringUtils.isEmpty(name)||StringUtils.isEmpty(password)){ msg = "用户名或密码不能为空"; map.addAttribute("msg", msg); return "/login/login.jsp"; } try { subject.login(token); }/*catch (RpcException e){ msg = "与服务器连接失败,请联系管理员"; map.addAttribute("msg", msg); return "/login/login.jsp"; }*//**/ catch ( UnknownAccountException uae ) { msg = "用户名或密码错误."; map.addAttribute("msg", msg); return "/login/login.jsp"; } catch (ExcessiveAttemptsException e) { msg = "登录失败次数过多"; map.addAttribute("msg", msg); return "/login/login.jsp"; } catch (LockedAccountException e) { msg = "帐号已被锁定."; map.addAttribute("msg", msg); return "/login/login.jsp"; } catch (DisabledAccountException e) { msg = "帐号已被禁用."; map.addAttribute("msg", msg); return "/login/login.jsp"; } catch (ExpiredCredentialsException e) { msg = "帐号已过期. "; map.addAttribute("msg", msg); return "/login/login.jsp"; } catch (UnauthorizedException e) { msg = "您没有得到相应的授权!" + e.getMessage(); map.addAttribute("msg", msg); return "/login/login.jsp"; } catch (AuthenticationException e) { msg = "用户名或密码错误"; map.addAttribute("msg", msg); return "/login/login.jsp"; } return "redirect:/successLogin.do"; } /** * * 功能描述:(无权访问跳转方法) * @author linjm * @date 2015年12月27日 下午3:18:35 * * @param @return * @param @throws Exception * @return String * @mender (修改者) * @update(修改内容-简单描述) * @updatetime(修改时间) */ @RequestMapping("refuse") public String refuse()throws Exception{ //重定向到登录页面 return "/refuse.jsp"; } /** * * 功能描述:(权限认证后加载页面) * @author linjm * @date 2015年12月27日 下午3:18:35 * * @param @return * @param @throws Exception * @return String * @mender (修改者) * @update(修改内容-简单描述) * @updatetime(修改时间) */ @RequestMapping("successLogin") @SystemControllerLog(description="登陆管理-成功登陆") public String successLogin() { Subject currentUser = SecurityUtils.getSubject(); //将用户信息和菜单信息存放在session中 Session session = currentUser.getSession(); User user=(User) currentUser.getPrincipal(); String roleName=roleService.getRole(user.getRole()).getName(); List<Menu> menus=null; if(roleName.equals("超级管理员")){ menus = menuService.getRootMenus(); }else{ menus = menuService.getMenus(user.getRole().getRoleId()); } session.setAttribute("menus", menus); session.setAttribute("user", user); InetAddress ia=null; try { ia=ia.getLocalHost(); String localname=ia.getHostName(); String localip=ia.getHostAddress(); System.out.println("#############本机名称是:"+ localname); System.out.println("######################本机的ip是 :"+localip); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return "/index_ims.jsp"; } @RequestMapping("outLogin") public String outLogin(HttpServletResponse httpresponse) { Subject subject = SecurityUtils.getSubject(); /* User user=(User) subject.getPrincipal(); if(user!=null){ Cookie cookie = new Cookie("user", null); cookie.setMaxAge(0); // 如果参数是0,就说明立即删除 httpresponse.addCookie(cookie); }*/ if (subject != null) { subject.logout(); } return "/login/login.jsp"; } /** * * 功能描述:(手动清楚缓存) * @author linjm * @date 2015年12月27日 下午3:18:35 * * @param @return * @param @throws Exception * @return String * @mender (修改者) * @update(修改内容-简单描述) * @updatetime(修改时间) */ /* @RequestMapping("clearShiroCache") public String clearShiroCache(){ //清除缓存,将来正常开发要在service调用customRealm.clearCached() customRealm.clearCached(); return "success"; }*/ }
<!--sessionIdCookie的实现,用于重写覆盖容器默认的JSESSIONID-->
<beanid="sharesession"class="org.apache.shiro.web.servlet.SimpleCookie">
<!--cookie的name,对应的默认是JSESSIONID-->
<constructor-argname="name"value="SHAREJSESSIONID"/>
<!--jsessionId的path为/用于多个系统共享jsessionId-->
<propertyname="path"value="/"/>
<propertyname="httpOnly"value="true"/>
</bean>
<!--sessionManager-->
<beanid="sessionManager"class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<!--设置全局会话超时时间,默认30分钟(1800000)-->
<propertyname="globalSessionTimeout"value="1800000"/>
<!--是否在会话过期后会调用SessionDAO的delete方法删除会话默认true-->
<propertyname="deleteInvalidSessions"value="true"/>
<!--会话验证器调度时间-->
<propertyname="sessionValidationInterval"value="1800000"/>
<!--session存储的实现-->
<propertyname="sessionDAO"ref="redisSessionDAO"/>
<!--sessionIdCookie的实现,用于重写覆盖容器默认的JSESSIONID-->
<propertyname="sessionIdCookie"ref="sharesession"/>
<!--定时检查失效的session-->
<propertyname="sessionValidationSchedulerEnabled"value="true"/>
</bean>
复写 JSESSIONID 同时由于shiro的原因你会发现系统访问一次url会多次调用doReadSession方法产生大量的redisio读取,建议在doReadSession方法添加二级缓存~
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。