获取源码和笔记地址:https://gitee.com/monologue_zsj/shiro.git (上篇文章地址:https://blog.csdn.net/weixin_42047611/article/details/114519799)
3、使用CacheManager
3.1Ehcahe
Shiro中默认使用Ehcahe实现缓存
<!--shiro-ehcache-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.5.3</version>
</dependency>
/**
* Created by Monologue_zsj on 2021/3/7 14:38
* Author:小脸儿红扑扑
* Description:整合Shiro框架相关的配置类
*/
@Configuration
public class ShiroConfig {
...
//3、创建自定义Realm
@Bean
public Realm getRealm() {
CustomerRealm customerRealm = new CustomerRealm();
//修改凭证校验匹配器
HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
//设置加密算法为md5
credentialsMatcher.setHashAlgorithmName("MD5");
//设置散列次数
credentialsMatcher.setHashIterations(1024);
customerRealm.setCredentialsMatcher(credentialsMatcher);
//开启缓存管理
customerRealm.setCacheManager(new EhCacheManager());
customerRealm.setCachingEnabled(true); //开启全局缓存
customerRealm.setAuthenticationCachingEnabled(true); //开启认证缓存
customerRealm.setAuthenticationCacheName("authenticationCache");
customerRealm.setAuthorizationCachingEnabled(true); //开启授权缓存
customerRealm.setAuthorizationCacheName("authorizationCache");
return customerRealm;
}
}
3.2 Redis缓存
<!--SpringBoot整合redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
spring.redis.port=6379
spring.redis.host=127.0.0.1
spring.redis.database=0
Caused by: java.io.NotSerializableException: org.apache.shiro.util.SimpleByteSource:由于salt没有序列化导致
/**
* Created by Monologue_zsj on 2021/3/7 20:50
* Author:小脸儿红扑扑
* Description:自定义Salt 实现序列化接口
*/
public class MyByteSource extends SimpleByteSource implements Serializable {
public MyByteSource(String string) {
super(string);
}
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("_________________________");
String principal = (String) token.getPrincipal();
//在工厂中获取service对象
UserService userService = (UserService) ApplicationContextUtils.getBean("userServiceImpl");
User user = userService.findByUserName(principal);
if (!ObjectUtils.isEmpty(user)) {
return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), new MyByteSource(user.getSalt()),//这个位置 this.getName());
}
return null;
}
/**
* Created by Monologue_zsj on 2021/3/7 19:54
* Author:小脸儿红扑扑
* Description:自定义shiro缓存管理器
*/
public class RedisCacheManager implements CacheManager {
/**
* @param cacheName 认证或者授权缓存的统一名称
* @param <K>
* @param <V>
* @return
* @throws CacheException
*/
@Override
public <K, V> Cache<K, V> getCache(String cacheName) throws CacheException {
System.out.println(cacheName);
return new RedisCache<K,V>(cacheName);
}
}
/**
* Created by Monologue_zsj on 2021/3/7 20:23
* Author:小脸儿红扑扑
* Description:自定义redis缓存实现
*/
public class RedisCache<K,V> implements Cache<K,V> {
private String cacheName;
public RedisCache() {
}
public RedisCache(String cacheName) {
this.cacheName = cacheName;
}
@Override
public V get(K k) throws CacheException {
System.out.println("get key: " + k);
return (V) getRedisTemplate().opsForHash().get(this.cacheName, k.toString());
}
@Override
public V put(K k, V v) throws CacheException {
System.out.println("put key: " + k);
System.out.println("put value: " + v);
getRedisTemplate().opsForHash().put(this.cacheName, k.toString(), v);
return null;
}
@Override
public V remove(K k) throws CacheException {
return (V) getRedisTemplate().opsForHash().delete(this.cacheName, k.toString());
}
@Override
public void clear() throws CacheException {
getRedisTemplate().delete(this.cacheName);
}
@Override
public int size() {
return getRedisTemplate().opsForHash().size(this.cacheName).intValue();
}
@Override
public Set<K> keys() {
return getRedisTemplate().opsForHash().keys(this.cacheName);
}
@Override
public Collection<V> values() {
return getRedisTemplate().opsForHash().values(this.cacheName);
}
private RedisTemplate getRedisTemplate() {
RedisTemplate redisTemplate = (RedisTemplate) ApplicationContextUtils.getBean("redisTemplate");
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
return redisTemplate;
}
}
//3、创建自定义Realm
@Bean
public Realm getRealm() {
...
//开启缓存管理
// customerRealm.setCacheManager(new EhCacheManager());
customerRealm.setCacheManager(new RedisCacheManager());
...
return customerRealm;
}
4、shiro-thymeleaf
<!--shrio-thymeleaf-->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.3.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>1.5.3</version>
</dependency>
@Configuration
public class ShiroConfig {
/**
* 配置方言,使Shiro标签生效
* @return
*/
@Bean(name = "shiroDialect")
public ShiroDialect shiroDialect() {
return new ShiroDialect();
}
...
}
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org/"
xmlns:shiro="http://www.pollix.at/thymeleaf/shiro" >
<head>
<meta charset="UTF-8">
<title>主页</title>
</head>
<body>
<!--获取身份信息-->
<span shiro:principal=""></span>
<!--认证处理-->
<span shiro:authenticated="">
认证通过展示的内容
</span>
<span shiro:notAuthenticated="" >
没有认证通过展示的内容
</span>
<!--授权角色-->
<span shiro:hasRole="admin">
this is admin
</span>
<!--授权资源-->
<span shiro:hasPermission="user:*:01">
具有用户模块的权限
</span>
</body>
</html>