spring boot shiro redis续

本篇文章是基于前几篇spring boot shiro redis的基础上,如果未看前几篇建议先看前几篇

1:springboot redis整合

2:springboot shiro整合

3:springboot shiro redis整合

4:spring boot shiro redis整合遇到的问题

spring boot shiro 使用redis对session进行管理请看 第3篇文章

shiro的认证,授权信息 也可以交给redis管理
本篇文章会和之前的使用redis管理session的那篇文章有些区别,对session的管理进行了重新实现
shiro的认证,授权信息 有redis管理的思想是:
shiro的认证,授权信息本身支持存放到缓存中,只需把之前shiro默认的ehcache缓存更换成redis缓存即可。

shiro 配置文件如下:重点的会使用红色标注:

package com.zyc.springboot.config;import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.servlet.Filter;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.session.SessionListener;
import org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.filter.DelegatingFilterProxy;import com.zyc.springboot.shiro.MyFormAuthenticationFilter;
import com.zyc.springboot.shiro.MyRealm;
import com.zyc.springboot.shiro.MyShiroSessionListener;
import com.zyc.springboot.shiro.RedisUtil;
import com.zyc.springboot.shiro.SessionDao;
import com.zyc.springboot.shiro.ShiroRedisCacheManager;@Configuration
public class ShiroConfig {/*@Bean(name = "shiroEhcacheManager")public EhCacheManager getEhCacheManager() {EhCacheManager em = new EhCacheManager();em.setCacheManagerConfigFile("classpath:ehcache-shiro.xml");return em;}*/@Bean(name="shiroRedisCacheManager")public ShiroRedisCacheManager shiroRedisCacheManager(RedisTemplate redisTemplate){ShiroRedisCacheManager shiroRedisCacheManager=new ShiroRedisCacheManager();shiroRedisCacheManager.setRedisTemplate(redisTemplate);return shiroRedisCacheManager;}@Bean(name = "lifecycleBeanPostProcessor")public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {LifecycleBeanPostProcessor lifecycleBeanPostProcessor = new LifecycleBeanPostProcessor();return lifecycleBeanPostProcessor;}@Bean(name = "sessionValidationScheduler")public ExecutorServiceSessionValidationScheduler getExecutorServiceSessionValidationScheduler(DefaultWebSessionManager defaultWebSessionManager) {ExecutorServiceSessionValidationScheduler scheduler = new ExecutorServiceSessionValidationScheduler();scheduler.setInterval(50*1000);scheduler.setSessionManager(defaultWebSessionManager);return scheduler;}@Beanpublic HashedCredentialsMatcher hashedCredentialsMatcher() {HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();hashedCredentialsMatcher.setHashAlgorithmName("md5");// 散列算法:这里使用MD5算法;hashedCredentialsMatcher.setHashIterations(1);// 散列的次数,比如散列两次,相当于md5(md5(""));hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);return hashedCredentialsMatcher;}@Bean(name = "defaultWebSecurityManager")public DefaultWebSecurityManager defaultWebSecurityManager(MyRealm myRealm,DefaultWebSessionManager defaultWebSessionManager,ShiroRedisCacheManager shiroRedisCacheManager) {DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();defaultWebSecurityManager.setRealm(myRealm);//defaultWebSecurityManager.setCacheManager(getEhCacheManager());defaultWebSecurityManager.setCacheManager(shiroRedisCacheManager);defaultWebSecurityManager.setSessionManager(defaultWebSessionManager);defaultWebSecurityManager.setRememberMeManager(rememberMeManager());return defaultWebSecurityManager;}@Bean(name = "rememberMeCookie")public SimpleCookie rememberMeCookie() {// 这个参数是cookie的名称,对应前端的checkbox的name = rememberMeSimpleCookie simpleCookie = new SimpleCookie("rememberMe");// simpleCookie.setMaxAge(60*60*24*30);return simpleCookie;}/*** cookie管理对象;* * @return*/@Bean(name = "rememberMeManager")public CookieRememberMeManager rememberMeManager() {CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();cookieRememberMeManager.setCookie(rememberMeCookie());byte[] cipherKey = Base64.decode("wGiHplamyXlVB11UXWol8g==");cookieRememberMeManager.setCipherKey(cipherKey);return cookieRememberMeManager;}@Bean@DependsOn(value = "lifecycleBeanPostProcessor")public MyRealm myRealm(ShiroRedisCacheManager shiroRedisCacheManager) {MyRealm myRealm = new MyRealm();//启用缓存myRealm.setCachingEnabled(true);//启用授权缓存myRealm.setAuthorizationCachingEnabled(true);myRealm.setAuthorizationCacheName("shiro-AutorizationCache");//启用认证信息缓存myRealm.setAuthenticationCachingEnabled(true);myRealm.setAuthenticationCacheName("shiro-AuthenticationCache");myRealm.setCacheManager(shiroRedisCacheManager);myRealm.setCredentialsMatcher(hashedCredentialsMatcher());return myRealm;}@Bean@DependsOn("lifecycleBeanPostProcessor")public DefaultAdvisorAutoProxyCreator getAutoProxyCreator(){DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();creator.setProxyTargetClass(true);return creator;}@Beanpublic AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(DefaultWebSecurityManager defaultWebSecurityManager) {AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();aasa.setSecurityManager(defaultWebSecurityManager);return aasa;}@Bean(name = "sessionManager")public DefaultWebSessionManager defaultWebSessionManager(SessionDao sessionDao) {DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();sessionManager.setGlobalSessionTimeout(1000*60*60*24*60);
//		//url中是否显示session IdsessionManager.setSessionIdUrlRewritingEnabled(false);
//		// 删除失效的sessionsessionManager.setDeleteInvalidSessions(true);sessionManager.setSessionValidationSchedulerEnabled(true);sessionManager.setSessionValidationInterval(18000000);sessionManager.setSessionValidationScheduler(getExecutorServiceSessionValidationScheduler(sessionManager));//sessionManager.setSessionValidationScheduler(quartzSessionValidationScheduler2(sessionManager));//设置SessionIdCookie 导致认证不成功,不从新设置新的cookie,从sessionManager获取sessionIdCookie//sessionManager.setSessionIdCookie(simpleIdCookie());sessionManager.getSessionIdCookie().setName("session-z-id");sessionManager.getSessionIdCookie().setPath("/");sessionManager.getSessionIdCookie().setMaxAge(60*60*24*7);sessionManager.setSessionDAO(sessionDao);Collection c=new ArrayList<>();c.add(new MyShiroSessionListener());sessionManager.setSessionListeners(c);return sessionManager;}//	@Bean
//	public QuartzSessionValidationScheduler2 quartzSessionValidationScheduler2(DefaultWebSessionManager sessionManager){
//		QuartzSessionValidationScheduler2 quartzSessionValidationScheduler2=new QuartzSessionValidationScheduler2();
//		quartzSessionValidationScheduler2.setSessionManager(sessionManager);
//		quartzSessionValidationScheduler2.setSessionValidationInterval(1000*5);
//		return quartzSessionValidationScheduler2;
//	} @Beanpublic SessionDao sessionDao(RedisUtil redisUtil,ShiroRedisCacheManager shiroRedisCacheManager) {SessionDao sessionDao = new SessionDao();//设置缓存器的名称sessionDao.setActiveSessionsCacheName("shiro-activeSessionCache1");//注入缓存管理器默认的是ehcache缓存sessionDao.setCacheManager(shiroRedisCacheManager);//注入缓存管理器2(实现session由redis控制有多种方法,上一步是一种,下面这样写也行)sessionDao.setRedisUtil(redisUtil);return sessionDao;}@Beanpublic RedisUtil redisUtil(RedisTemplate redisTemplate) {RedisUtil redisUtil = new RedisUtil();redisUtil.setRedisTemplate(redisTemplate);return redisUtil;}@Bean(name = "filterRegistrationBean1")public FilterRegistrationBean filterRegistrationBean() {FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();filterRegistrationBean.setFilter(new DelegatingFilterProxy("shiroFilter"));filterRegistrationBean.addInitParameter("targetFilterLifecycle", "true");filterRegistrationBean.setEnabled(true);filterRegistrationBean.addUrlPatterns("/");
//		filterRegistrationBean.setDispatcherTypes(DispatcherType.REQUEST,
//				DispatcherType.FORWARD, DispatcherType.INCLUDE,
//				DispatcherType.ERROR);return filterRegistrationBean;}@Bean(name = "shiroFilter")public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager) {// SecurityUtils.setSecurityManager(defaultWebSecurityManager);ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();shiroFilterFactoryBean.setLoginUrl("/login");shiroFilterFactoryBean.setSuccessUrl("/getIndex");shiroFilterFactoryBean.setUnauthorizedUrl("/login");shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);Map filterMap1 = shiroFilterFactoryBean.getFilters();filterMap1.put("authc", new MyFormAuthenticationFilter());shiroFilterFactoryBean.setFilters(filterMap1);Map filterMap = new LinkedHashMap();filterMap.put("/static/**", "anon");filterMap.put("/api/**", "anon");filterMap.put("/logout", "anon");filterMap.put("/login", "authc");filterMap.put("/**", "authc");shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);return shiroFilterFactoryBean;}}
@Bean(name="shiroRedisCacheManager")public ShiroRedisCacheManager shiroRedisCacheManager(RedisTemplate redisTemplate){ShiroRedisCacheManager shiroRedisCacheManager=new ShiroRedisCacheManager();shiroRedisCacheManager.setRedisTemplate(redisTemplate);return shiroRedisCacheManager;}@Bean(name = "lifecycleBeanPostProcessor")public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {LifecycleBeanPostProcessor lifecycleBeanPostProcessor = new LifecycleBeanPostProcessor();return lifecycleBeanPostProcessor;}@Bean(name = "sessionValidationScheduler")public ExecutorServiceSessionValidationScheduler getExecutorServiceSessionValidationScheduler(DefaultWebSessionManager defaultWebSessionManager) {ExecutorServiceSessionValidationScheduler scheduler = new ExecutorServiceSessionValidationScheduler();scheduler.setInterval(50*1000);scheduler.setSessionManager(defaultWebSessionManager);return scheduler;}@Beanpublic HashedCredentialsMatcher hashedCredentialsMatcher() {HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();hashedCredentialsMatcher.setHashAlgorithmName("md5");// 散列算法:这里使用MD5算法;hashedCredentialsMatcher.setHashIterations(1);// 散列的次数,比如散列两次,相当于md5(md5(""));hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);return hashedCredentialsMatcher;}@Bean(name = "defaultWebSecurityManager")public DefaultWebSecurityManager defaultWebSecurityManager(MyRealm myRealm,DefaultWebSessionManager defaultWebSessionManager,ShiroRedisCacheManager shiroRedisCacheManager) {DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();defaultWebSecurityManager.setRealm(myRealm);//defaultWebSecurityManager.setCacheManager(getEhCacheManager());defaultWebSecurityManager.setCacheManager(shiroRedisCacheManager);defaultWebSecurityManager.setSessionManager(defaultWebSessionManager);defaultWebSecurityManager.setRememberMeManager(rememberMeManager());return defaultWebSecurityManager;}@Bean(name = "rememberMeCookie")public SimpleCookie rememberMeCookie() {// 这个参数是cookie的名称,对应前端的checkbox的name = rememberMeSimpleCookie simpleCookie = new SimpleCookie("rememberMe");// simpleCookie.setMaxAge(60*60*24*30);return simpleCookie;}/*** cookie管理对象;* * @return*/@Bean(name = "rememberMeManager")public CookieRememberMeManager rememberMeManager() {CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();cookieRememberMeManager.setCookie(rememberMeCookie());byte[] cipherKey = Base64.decode("wGiHplamyXlVB11UXWol8g==");cookieRememberMeManager.setCipherKey(cipherKey);return cookieRememberMeManager;}@Bean@DependsOn(value = "lifecycleBeanPostProcessor")public MyRealm myRealm(ShiroRedisCacheManager shiroRedisCacheManager) {MyRealm myRealm = new MyRealm();//启用缓存myRealm.setCachingEnabled(true);//启用授权缓存myRealm.setAuthorizationCachingEnabled(true);myRealm.setAuthorizationCacheName("shiro-AutorizationCache");//启用认证信息缓存myRealm.setAuthenticationCachingEnabled(true);myRealm.setAuthenticationCacheName("shiro-AuthenticationCache");myRealm.setCacheManager(shiroRedisCacheManager);myRealm.setCredentialsMatcher(hashedCredentialsMatcher());return myRealm;}@Bean@DependsOn("lifecycleBeanPostProcessor")public DefaultAdvisorAutoProxyCreator getAutoProxyCreator(){DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();creator.setProxyTargetClass(true);return creator;}@Beanpublic AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(DefaultWebSecurityManager defaultWebSecurityManager) {AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();aasa.setSecurityManager(defaultWebSecurityManager);return aasa;}@Bean(name = "sessionManager")public DefaultWebSessionManager defaultWebSessionManager(SessionDao sessionDao) {DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();sessionManager.setGlobalSessionTimeout(1000*60*60*24*60);
//		//url中是否显示session IdsessionManager.setSessionIdUrlRewritingEnabled(false);
//		// 删除失效的sessionsessionManager.setDeleteInvalidSessions(true);sessionManager.setSessionValidationSchedulerEnabled(true);sessionManager.setSessionValidationInterval(18000000);sessionManager.setSessionValidationScheduler(getExecutorServiceSessionValidationScheduler(sessionManager));//sessionManager.setSessionValidationScheduler(quartzSessionValidationScheduler2(sessionManager));//设置SessionIdCookie 导致认证不成功,不从新设置新的cookie,从sessionManager获取sessionIdCookie//sessionManager.setSessionIdCookie(simpleIdCookie());sessionManager.getSessionIdCookie().setName("session-z-id");sessionManager.getSessionIdCookie().setPath("/");sessionManager.getSessionIdCookie().setMaxAge(60*60*24*7);sessionManager.setSessionDAO(sessionDao);Collection c=new ArrayList<>();c.add(new MyShiroSessionListener());sessionManager.setSessionListeners(c);return sessionManager;}//	@Bean
//	public QuartzSessionValidationScheduler2 quartzSessionValidationScheduler2(DefaultWebSessionManager sessionManager){
//		QuartzSessionValidationScheduler2 quartzSessionValidationScheduler2=new QuartzSessionValidationScheduler2();
//		quartzSessionValidationScheduler2.setSessionManager(sessionManager);
//		quartzSessionValidationScheduler2.setSessionValidationInterval(1000*5);
//		return quartzSessionValidationScheduler2;
//	} @Beanpublic SessionDao sessionDao(RedisUtil redisUtil,ShiroRedisCacheManager shiroRedisCacheManager) {SessionDao sessionDao = new SessionDao();//设置缓存器的名称sessionDao.setActiveSessionsCacheName("shiro-activeSessionCache1");//注入缓存管理器默认的是ehcache缓存sessionDao.setCacheManager(shiroRedisCacheManager);//注入缓存管理器2(实现session由redis控制有多种方法,上一步是一种,下面这样写也行)sessionDao.setRedisUtil(redisUtil);return sessionDao;}@Beanpublic RedisUtil redisUtil(RedisTemplate redisTemplate) {RedisUtil redisUtil = new RedisUtil();redisUtil.setRedisTemplate(redisTemplate);return redisUtil;}@Bean(name = "filterRegistrationBean1")public FilterRegistrationBean filterRegistrationBean() {FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();filterRegistrationBean.setFilter(new DelegatingFilterProxy("shiroFilter"));filterRegistrationBean.addInitParameter("targetFilterLifecycle", "true");filterRegistrationBean.setEnabled(true);filterRegistrationBean.addUrlPatterns("/");
//		filterRegistrationBean.setDispatcherTypes(DispatcherType.REQUEST,
//				DispatcherType.FORWARD, DispatcherType.INCLUDE,
//				DispatcherType.ERROR);return filterRegistrationBean;}@Bean(name = "shiroFilter")public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager) {// SecurityUtils.setSecurityManager(defaultWebSecurityManager);ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();shiroFilterFactoryBean.setLoginUrl("/login");shiroFilterFactoryBean.setSuccessUrl("/getIndex");shiroFilterFactoryBean.setUnauthorizedUrl("/login");shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);Map filterMap1 = shiroFilterFactoryBean.getFilters();filterMap1.put("authc", new MyFormAuthenticationFilter());shiroFilterFactoryBean.setFilters(filterMap1);Map filterMap = new LinkedHashMap();filterMap.put("/static/**", "anon");filterMap.put("/api/**", "anon");filterMap.put("/logout", "anon");filterMap.put("/login", "authc");filterMap.put("/**", "authc");shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);return shiroFilterFactoryBean;}}

ShiroRedisCacheManager实现如下:

package com.zyc.springboot.shiro;import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.cache.CacheManager;
import org.springframework.data.redis.core.RedisTemplate;/*** ClassName: ShiroRedisCacheManager   * @author zyc-admin* @date 2018年3月1日  * @Description: TODO  */
public class ShiroRedisCacheManager implements CacheManager {private RedisTemplate redisTemplate;public RedisTemplate getRedisTemplate() {return redisTemplate;}public void setRedisTemplate(RedisTemplate redisTemplate) {this.redisTemplate = redisTemplate;}@Overridepublic  Cache getCache(String arg0) throws CacheException {// TODO Auto-generated method stubreturn new ShiroRedisCache<>(arg0,redisTemplate);}}

ShiroRedisCache实现如下:

package com.zyc.springboot.shiro;import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.springframework.data.redis.core.RedisTemplate;/*** ClassName: ShiroRedisCache* * @author zyc-admin* @date 2018年3月1日* @Description: TODO*/
@SuppressWarnings("unchecked")
public class ShiroRedisCache implements Cache {private String cacheKey;private RedisTemplate redisTemplate;public ShiroRedisCache(String name, RedisTemplate redisTemplate) {this.cacheKey="shiro:cache:" + name + ":";this.redisTemplate=redisTemplate;}@Overridepublic void clear() throws CacheException {// TODO Auto-generated method stubredisTemplate.delete(keys());}@Overridepublic V get(K arg0) throws CacheException {return (V) redisTemplate.opsForValue().get(getCacheKey(arg0));}@Overridepublic Set keys() {return redisTemplate.keys(getCacheKey("*"));}@Overridepublic V put(K arg0, V arg1) throws CacheException {V old = get(arg0);redisTemplate.boundValueOps(getCacheKey(arg0)).set(arg1);redisTemplate.expire(getCacheKey(arg0), 1, TimeUnit.HOURS);return old;}@Overridepublic V remove(K arg0) throws CacheException {V old = get(arg0);redisTemplate.delete(getCacheKey(arg0));return old;}@Overridepublic int size() {return keys().size();}@Overridepublic Collection values() {Set keys = keys();List list = new ArrayList<>();for (K s : keys) {list.add(get(s));}return list;}public String getCacheKey() {return cacheKey;}public K getCacheKey(Object arg0) {return (K) (cacheKey + arg0);}public void setCacheKey(String cacheKey) {this.cacheKey = cacheKey;}public RedisTemplate getRedisTemplate() {return redisTemplate;}public void setRedisTemplate(RedisTemplate redisTemplate) {this.redisTemplate = redisTemplate;}}

对shiro的认证,授权信息 缓存 还需要对MyRealm进行部分重写如下:在退出的时候清除缓存(你也可不清除,看自己项目需求)

package com.zyc.springboot.shiro;import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.beanutils.BeanUtils;
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.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.subject.PrincipalCollection;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zyc.springboot.entity.User;
import com.zyc.springboot.service.AccountService;
import com.zyc.springboot.util.SpringContext;public class MyRealm extends AuthorizingRealm {@Overridepublic CacheManager getCacheManager() {// TODO Auto-generated method stubreturn super.getCacheManager();}/*** 权限认证*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {System.out.println("授权=====");// 获取登录用户的信息,在认证时存储的是ShiroUser 所以得到的就是ShiroUser// 在其他地方也可通过SecurityUtils.getSubject().getPrincipals()获取用户信息String userName = principals.getPrimaryPrincipal().toString();// 权限字符串List permissions = new ArrayList<>();// 从数据库中获取对应权限字符串并存储permissionspermissions.add("111");// 角色字符串List roles = new ArrayList<>();// 从数据库中获取对应角色字符串并存储rolesSimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();simpleAuthorizationInfo.addStringPermissions(permissions);simpleAuthorizationInfo.addRoles(roles);// 角色类型return simpleAuthorizationInfo;}/*** 登录验证*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {System.out.println("认证=====");String userName = ((MyAuthenticationToken) arg0).getUsername();char[] password = ((MyAuthenticationToken) arg0).getPassword();User user = new User();// 根据用户名密码获取userObject obj = new SimpleHash("md5", new String(password), null, 1);user.setPassword(obj.toString());user.setUserName(userName);user = ((AccountService) SpringContext.getBean("accountService")).findByPw(user);if (user == null) {throw new AuthenticationException("用户名密码错误");}SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(userName, user.getPassword(), this.getName());return simpleAuthenticationInfo;}@Overrideprotected void doClearCache(PrincipalCollection principals) {// TODO Auto-generated method stubsuper.doClearCache(principals);clearCachedAuthenticationInfo(principals);clearCachedAuthorizationInfo(principals);}
@Overrideprotected void clearCachedAuthenticationInfo(PrincipalCollection principals) {// TODO Auto-generated method stubsuper.clearCachedAuthenticationInfo(principals);Object key = principals.getPrimaryPrincipal();// ShiroUser shiroUser=new ShiroUser();// try {// BeanUtils.copyProperties(shiroUser, key);// } catch (Exception e) {// // TODO Auto-generated catch block// }getAuthenticationCache().remove(key);}
@Overrideprotected void clearCachedAuthorizationInfo(PrincipalCollection principals) {// TODO Auto-generated method stubsuper.clearCachedAuthorizationInfo(principals);Object key = getAuthorizationCacheKey(principals);getAuthorizationCache().remove(key);}protected Object getAuthorizationCacheKey(PrincipalCollection principals) {return principals.getPrimaryPrincipal();}
}
@Overrideprotected void doClearCache(PrincipalCollection principals) {// TODO Auto-generated method stubsuper.doClearCache(principals);clearCachedAuthenticationInfo(principals);clearCachedAuthorizationInfo(principals);}
@Overrideprotected void clearCachedAuthenticationInfo(PrincipalCollection principals) {// TODO Auto-generated method stubsuper.clearCachedAuthenticationInfo(principals);Object key = principals.getPrimaryPrincipal();// ShiroUser shiroUser=new ShiroUser();// try {// BeanUtils.copyProperties(shiroUser, key);// } catch (Exception e) {// // TODO Auto-generated catch block// }getAuthenticationCache().remove(key);}
@Overrideprotected void clearCachedAuthorizationInfo(PrincipalCollection principals) {// TODO Auto-generated method stubsuper.clearCachedAuthorizationInfo(principals);Object key = getAuthorizationCacheKey(principals);getAuthorizationCache().remove(key);}protected Object getAuthorizationCacheKey(PrincipalCollection principals) {return principals.getPrimaryPrincipal();}
}

本篇redis缓存sessio的代码改动了如下:主要是sessiondao本身也支持缓存,之前没发现,现在使用自带的功能加以修正,简单方便

package com.zyc.springboot.shiro;import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.Serializable;import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.SimpleSession;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;public class SessionDao extends EnterpriseCacheSessionDAO {private String cacheKey="shiro:cache:shiro-activeSessionCache1:";private RedisUtil redisUtil;public RedisUtil getRedisUtil() {return redisUtil;}public void setRedisUtil(RedisUtil redisUtil) {this.redisUtil = redisUtil;}// 创建session,保存到数据库@Overrideprotected Serializable doCreate(Session session) {@SuppressWarnings("unused")Serializable sessionId = super.doCreate(session);//redisUtil.set(cacheKey+session.getId().toString(), sessionToByte(session),1*60L);  getCacheManager().getCache("shiro-activeSessionCache1").put(session.getId().toString(), session);return session.getId();}// 获取session@Overrideprotected Session doReadSession(Serializable sessionId) {// 先从缓存中获取session,如果没有再去数据库中获取//Session session = super.doReadSession(sessionId); 
//        if(session == null){
//            byte[] bytes = (byte[]) redisUtil.get(sessionId.toString());
//            if(bytes != null && bytes.length > 0){
//                session = byteToSession(bytes);    
//            }
//        }Session session = getActiveSessionsCache().get(sessionId);return session;}// 更新session的最后一次访问时间@Overrideprotected void doUpdate(Session session) {super.doUpdate(session);//redisUtil.set(session.getId().toString(), sessionToByte(session),1*60L); getActiveSessionsCache().put(session.getId().toString(), session);}// 删除session@Overrideprotected void doDelete(Session session) {System.out.println("doDelete......");
//        super.doDelete(session);
//        redisUtil.remove(session.getId().toString());getActiveSessionsCache().remove(session.getId().toString());}// 把session对象转化为byte保存到redis中public byte[] sessionToByte(Session session){ByteArrayOutputStream bo = new ByteArrayOutputStream();byte[] bytes = null;try {ObjectOutput oo = new ObjectOutputStream(bo);oo.writeObject(session);bytes = bo.toByteArray();} catch (IOException e) {e.printStackTrace();}return bytes;}// 把byte还原为sessionpublic Session byteToSession(byte[] bytes){ByteArrayInputStream bi = new ByteArrayInputStream(bytes);ObjectInputStream in;SimpleSession session = null;try {in = new ObjectInputStream(bi);session = (SimpleSession) in.readObject();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return session;}
}  getCacheManager().getCache("shiro-activeSessionCache1").put(session.getId().toString(), session);return session.getId();}// 获取session@Overrideprotected Session doReadSession(Serializable sessionId) {// 先从缓存中获取session,如果没有再去数据库中获取//Session session = super.doReadSession(sessionId); 
//        if(session == null){
//            byte[] bytes = (byte[]) redisUtil.get(sessionId.toString());
//            if(bytes != null && bytes.length > 0){
//                session = byteToSession(bytes);    
//            }
//        }Session session = getActiveSessionsCache().get(sessionId);return session;}// 更新session的最后一次访问时间@Overrideprotected void doUpdate(Session session) {super.doUpdate(session);//redisUtil.set(session.getId().toString(), sessionToByte(session),1*60L); getActiveSessionsCache().put(session.getId().toString(), session);}// 删除session@Overrideprotected void doDelete(Session session) {System.out.println("doDelete......");
//        super.doDelete(session);
//        redisUtil.remove(session.getId().toString());getActiveSessionsCache().remove(session.getId().toString());}// 把session对象转化为byte保存到redis中public byte[] sessionToByte(Session session){ByteArrayOutputStream bo = new ByteArrayOutputStream();byte[] bytes = null;try {ObjectOutput oo = new ObjectOutputStream(bo);oo.writeObject(session);bytes = bo.toByteArray();} catch (IOException e) {e.printStackTrace();}return bytes;}// 把byte还原为sessionpublic Session byteToSession(byte[] bytes){ByteArrayInputStream bi = new ByteArrayInputStream(bytes);ObjectInputStream in;SimpleSession session = null;try {in = new ObjectInputStream(bi);session = (SimpleSession) in.readObject();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return session;}
}
package com.zyc.zspringboot.shiro;import org.apache.shiro.session.Session;
import org.apache.shiro.session.SessionListener;import com.zyc.zspringboot.util.SpringContext;public class MyShiroSessionListener implements SessionListener {@Overridepublic void onStart(Session session) {}@Overridepublic void onStop(Session session) {// TODO 退出登录时,先调用此方法,然后会继续调用SessionDao中的doDelete方法System.out.println("onStop===" + session.getId());RedisUtil redisUtil = (RedisUtil) SpringContext.getBean("redisUtil");// 清除sessionredisUtil.remove(session.getId().toString());// 清除缓存redisUtil.remove("shiro:cache:shiro-activeSessionCache1:"+ session.getId().toString());}@Overridepublic void onExpiration(Session session) {System.out.println("onExpiration===" + session.getId());RedisUtil redisUtil = (RedisUtil) SpringContext.getBean("redisUtil");// 清除sessionredisUtil.remove(session.getId().toString());// 清除缓存redisUtil.remove("shiro:cache:shiro-activeSessionCache1:"+ session.getId().toString());}}

整合完毕,如果遇到部分问题,可以看之前写的几篇文章中是否已经提到并解决,也可留言提出问题,我及时更新改正


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部