在之前的文章中,介绍shiro一直从shiro的.ini文件的权限认证,到在自定义Realm中的权限认证的实现,到后期我们链接数据库的权限实现,然后是自定义Realm中授权信息实现,到链接数据库的授权实现。粗粒度的授权实现角色,以及细粒度的权限字符串的授权实现。我们都一一做了解释和Demo。那么我们现在要考虑到一个系统的雏形搭建起来之后,就要考虑到一些优化的小问题,逼如说我们的权限数据一般来说不会有太大的变动,然而我们这时做的权限,授权等等的操作一直都会访问数据库,如果我们的系统访问量很大,相应的访问首页的次数也会增多,此时我们就要考虑到调用权限验证的时候回对数据库造成不小的压力,此时就要引入缓存,将我们的权限认证,授权等操作的数据放入到缓存中会在一定程度上减轻我们数据库访问的压力。
那首先我们就要来大概先了解一下shiro中为我们提供了一个CacheManager的一个接口,我们日后就可以通过实现CacheManager接口来实现自定义缓存。
大概流程:

如上图所示,我们再Shiro中的认证授权,之前是自定义Realm直接去数据库中查询认证授权的数据,然后再放入缓存中去操作,而加入缓存管理器之后我们的自定义Realm会优先去缓存管理器中去找数据,如果要找的数据在缓存管理器中有,则直接使用,如果缓存管理器中没有则去数据库中查询然后放入缓存管理器中,以便下次查询使用。有一点要记住的是,我们要是用缓存的场景是查询多而增删改极少的时候才会用到缓存,如果增删改多的场景使用缓存,我们还要去维护缓存中的数据和数据库中的数据就有一些得不偿失了。
首先要引入ehcache的pom坐标:
<!--引入shiro和ehcache-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.5.3</version>
</dependency>
引入依赖之后,我们就要去ShiroConfig文件中去修改一下配置信息:
/**
* shiro配置类
*/
@Configuration
public class ShiroConfig {
//1.创建Shiro过滤器
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
Map<String, String> map = new HashMap<>();
map.put("/login.jsp", "anon");
map.put("/register.jsp", "anon");
map.put("/index.jsp", "authc");
shiroFilterFactoryBean.setLoginUrl("/login.jsp");
shiroFilterFactoryBean.setUnauthorizedUrl("/error.jsp”");
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
return shiroFilterFactoryBean;
}
//2.创建安全管理器
@Bean
public DefaultWebSecurityManager defaultWebSecurityManager(Realm realm) {
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
defaultWebSecurityManager.setRealm(realm);
return defaultWebSecurityManager;
}
//3.创建自定义Realm
@Bean
public Realm realm() {
MyRealm myRealm = new MyRealm();
//1.修改凭证匹配器
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("MD5");
hashedCredentialsMatcher.setHashIterations(1024);
myRealm.setCredentialsMatcher(hashedCredentialsMatcher);
//开启缓存管理
myRealm.setCacheManager(new EhCacheManager());
//开启全局缓存设置为true
myRealm.setCachingEnabled(true);
//开启认证的缓存设置为true
myRealm.setAuthenticationCachingEnabled(true);
//给认证数据在缓存中设置一个名字
myRealm.setAuthenticationCacheName("authenticationCache");
//开启授权的缓存设置为true
myRealm.setAuthorizationCachingEnabled(true);
//给授权数据在缓存中设置一个名字
myRealm.setAuthorizationCacheName("authorizationCache");
return myRealm;
}
}
上面的这段代码,在自定义Realm中我们可以看到我们开启了缓存管理,并开启全局缓存设置为true,然后开启认证数据的和授权数据的缓存,并且在缓存中给两个不同数据的两个不同的名字。开启授权和认证的缓存是在开启全局缓存的基础之上的。
可以看一下效果:
我在自定义Realm中往控制台输出了一段话:调用验证,然后登陆访问首页看一下控制台我们可以看到控制台输出了如下的话:

之后我们清掉控制台,再来刷新首页看一下控制台:

可以看到我们的缓存确实是起到了作用。
而这个ehcache的缓存是存在本地应用的缓存,如果我们的应用关闭或重启启动之后缓存就会消失,日后我们还考虑要将数据加入到redis中,这样不论我们应用是关闭或者重启,只要缓存的redis中有数据就会去缓存中查询。
1802



被折叠的 条评论
为什么被折叠?



