本文不涉及springboot
和shiro
及redis
的整合,主要讲如何使用redis实现授权缓存
。及过程中遇到的问题如何解决
1、需要引入依赖
<dependency>
<groupId>org.crazycake</groupId>
<artifactId>shiro-redis</artifactId>
<version>3.1.0</version>
</dependency>
2、ShiroConfig.java
完整配置
@Configuration
public class ShiroConfig {
/**
* 创建ShiroFilterFactoryBean
*/
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
//设置安全管理器
bean.setSecurityManager(defaultWebSecurityManager);
//添加Shiro内置过滤器
/**
* Shiro内置过滤器,可以实现权限相关的拦截器
* 常用的过滤器:
* anon: 无需认证(登录)可以访问
* authc: 必须认证才可以访问
* user: 如果使用rememberMe的功能可以直接访问
* perms: 该资源必须得到资源权限才可以访问
* role: 该资源必须得到角色权限才可以访问
*/
Map<String,String> filterMap = new LinkedHashMap<>();
filterMap.put("/index","authc");
filterMap.put("/web/**","authc");
bean.setFilterChainDefinitionMap(filterMap);
//设置未授权提示页面
//bean.setUnauthorizedUrl("/noAuth");
bean.setLoginUrl("/login");
return bean;
}
/**
* 创建DefaultWebSecurityManager
*
* 里面主要定义了登录,创建subject,登出等操作
*/
@Bean(name="securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//securityManager.setSessionManager(sessionManager());
securityManager.setRealm(userRealm);
//配置缓存管理 使用redis
securityManager.setCacheManager(cacheManager());
//配置session管理 使用redis
securityManager.setSessionManager(sessionManager());
return securityManager;
}
@Bean
public DefaultWebSessionManager sessionManager(){
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
sessionManager.setSessionIdUrlRewritingEnabled(false);
//配置redis sessionDao
sessionManager.setSessionDAO(redisSessionDAO());
return sessionManager;
}
/**
*整合shiroDialect:用来整合 shiro与thymeleaf
*/
@Bean
public ShiroDialect shiroDialect(){
return new ShiroDialect();
}
/**
*创建realm 对象 需要自己定义realm
*/
@Bean(name="userRealm")
public UserRealm userRealm(){
UserRealm userRealm = new UserRealm();
//启用授权缓存,即缓存AuthorizationInfo信息,默认false
userRealm.setAuthorizationCachingEnabled(true);
return new UserRealm();
}
//下面开始配置shiro—redis
/**
* cacheManager 缓存 redis实现
* @return
*/
public RedisCacheManager cacheManager() {
RedisCacheManager redisCacheManager = new RedisCacheManager();
redisCacheManager.setRedisManager(redisManager());
//这里配置缓存是通过用户对象中的哪个字段来作为唯一标识的,自己根据字段更改即可
redisCacheManager.setPrincipalIdFieldName("userAccount");
//用户权限信息缓存时间
redisCacheManager.setExpire(200000);
return redisCacheManager;
}
/**
* 配置shiro redisManager
* @return
*/
public RedisManager redisManager() {
RedisManager redisManager = new RedisManager();
redisManager.setHost("127.0.0.1");
// 配置过期时间
redisManager.setTimeout(1800);
return redisManager;
}
/**
* RedisSessionDAO shiro sessionDao层的实现
*/
@Bean
public RedisSessionDAO redisSessionDAO() {
RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
redisSessionDAO.setRedisManager(redisManager());
return redisSessionDAO;
}
}
3、以上就已经配置完毕了,下面是可能会遇到的异常及解决方法。
3.1、类型转换异常
`java.lang.ClassCastException: com.xxx.entity.User cannot be cast to com.xxx.entity.User`
原因分析:
项目中使用了spring-boot-devtools
热部署,导致类加载不统一。
解决方法:
1)去掉spring-boot-devtools
热部署依赖,但是会导致开发效率降低。
2)网上流传比较广的方法
在resources
文件夹下创建META-INF/spring-devtools.properties
在文件中写入
restart.include.shiro=/shiro-[\\w-\\.]+jar
3.2、在使用了shiro
权限认证的页面报出thymeleaf
的异常
Error during execution of processor 'at.pollux.thymeleaf.shiro.processor.element.PrincipalElementProcessor'
原因分析:
在3.1中使用了第二种解决方法,具体不知道为啥。
解决方法:
在resources/META-INF/spring-devtools.properties
文件中再写入下面这段代码
restart.include.thymeleaf.extras.shiro=/thymeleaf-extras-shiro-[\\w-\\.]+jar