springboot②The most correct integration of shiro and use of ehcache cache

https://blog.csdn.net/tanleijin/java/article/details/81118963

When springboot integrates shiro and ehcache, it must first integrate ehcache and then shiro, so that it can be used directly when shiro configures cacheManager. Here are the correct integration steps: The
first step is to integrate ehcache:
1. Introduce the following dependencies in the pom.xml file


org.springframework.boot
spring-boot-starter-cache



net.sf.ehcache
ehcache

2. Introduce the configuration file ehcache.xml

The specific content of ehcache.xml:

<?xml version="1.0" encoding="UTF-8"?>


<!-- 这里的 users 缓存空间是为了下面的 demo 做准备 -->
<cache
        name="users"
        eternal="false"
        maxElementsInMemory="100"
        overflowToDisk="false"
        diskPersistent="false"
        timeToIdleSeconds="0"
        timeToLiveSeconds="300"
        memoryStoreEvictionPolicy="LRU" />
ehcache.xml file configuration detailed explanation Part of the information comes from the network diskStore: the cache path, ehcache is divided into memory and disk two levels, this attribute defines the disk cache location. defaultCache: The default cache strategy, when ehcache cannot find the defined cache, this cache strategy is used. Only one can be defined. name: cache name. maxElementsInMemory: the maximum number of caches maxElementsOnDisk: the maximum number of caches on the hard disk. eternal: Whether the object is permanently valid, once it is set, timeout will not work. overflowToDisk: whether to save to disk, when the system is down timeToIdleSeconds: set the allowable idle time (unit: seconds) before the object expires. Only used when the eternal=false object is not permanently valid, an optional attribute, the default value is 0, that is, the idle time is infinite. timeToLiveSeconds: Set the allowed survival time (unit: seconds) of the object before it expires. The maximum time is between the creation time and the expiration time. It is used only when eternal=false object is not permanently valid, the default is 0. That is, the object lifetime is infinite. diskPersistent: Whether to cache data during the restart period of the virtual machine. Whether the disk store persists between restarts of the Virtual Machine. The default value is false. diskSpoolBufferSizeMB: This parameter sets the buffer size of DiskStore (disk cache). The default is 30MB. Each Cache should have its own buffer. diskExpiryThreadIntervalSeconds: The running interval of disk failure threads, the default is 120 seconds. memoryStoreEvictionPolicy: When the maxElementsInMemory limit is reached, Ehcache will clean up the memory according to the specified policy. The default strategy is LRU (least recently used). You can set it to FIFO (first in first out) or LFU (less used). clearOnFlush: Whether to clear when the amount of memory is maximum. memoryStoreEvictionPolicy: Optional policies are: LRU (least recently used, default policy), FIFO (first in first out), LFU (least access). FIFO, first in first out, LFU, Less Frequently Used, has been the least used. As mentioned above, the cached element has a hit attribute, and the one with the smallest hit value will be cleared from the cache. LRU, Least Recently Used, the least recently used. The cached element has a timestamp. When the cache capacity is full and you need to make room to cache new elements, then the timestamp in the existing cached element is away from the current time The farthest element will be cleared from the cache. 3. Add the startup annotation to the main class and add the annotation @EnableCaching to enable caching in the Spring Boot main class. @EnableCaching @MapperScan(basePackages = "com.tan.dream.**.dao") @SpringBootApplication public class DreamApplication { Optional strategies are: LRU (least recently used, default strategy), FIFO (first in first out), LFU (least access). FIFO, first in first out, LFU, Less Frequently Used, has been the least used. As mentioned above, the cached element has a hit attribute, and the one with the smallest hit value will be cleared from the cache. LRU, Least Recently Used, the least recently used. The cached element has a timestamp. When the cache capacity is full and you need to make room to cache new elements, then the timestamp in the existing cached element is away from the current time The farthest element will be cleared from the cache. 3. Add the startup annotation to the main class and add the annotation @EnableCaching to enable caching in the Spring Boot main class. @EnableCaching @MapperScan(basePackages = "com.tan.dream.**.dao") @SpringBootApplication public class DreamApplication { Optional strategies are: LRU (least recently used, default strategy), FIFO (first in first out), LFU (least access). FIFO, first in first out, LFU, Less Frequently Used, has been the least used. As mentioned above, the cached element has a hit attribute, and the one with the smallest hit value will be cleared from the cache. LRU, Least Recently Used, the least recently used. The cached element has a timestamp. When the cache capacity is full and you need to make room to cache new elements, then the timestamp in the existing cached element is away from the current time The farthest element will be cleared from the cache. 3. Add the startup annotation to the main class and add the annotation @EnableCaching to enable caching in the Spring Boot main class. @EnableCaching @MapperScan(basePackages = "com.tan.dream.**.dao") @SpringBootApplication public class DreamApplication {
public static void main(String[] args) {
	SpringApplication.run(DreamApplication.class, args);
}

} 4.
The caching annotations @Cacheable and @CachePut in springboot can be used (the specific use of caching annotations to be completed)

The focus is on the second step to integrate shiro and use ehcache cache:
1. Introduce the following dependencies in the pom.xml file


org.apache.shiro
shiro-spring
1.3.2



org.apache.shiro
shiro-ehcache
1.3.2

2. Write shiro Realm verification, of course, this is my shrio realm, need to make some modifications according to your own project
public class UserRealm extends AuthorizingRealm { /* @Autowired UserDao userMapper; @Autowired MenuService menuService;*/



/**
 * 授权
 * @param arg0
 * @return
 */
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {

	UserDO userDO = (UserDO)SecurityUtils.getSubject().getPrincipal();
	Long userId =  userDO.getUserId();
	MenuService menuService = ApplicationContextRegister.getBean(MenuService.class);
	Set<String> perms = menuService.listPerms(userId);
	SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
	info.setStringPermissions(perms);
	return info;
}

/**
 * 认证
 * @param token
 * @return
 * @throws AuthenticationException
 */
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
	String username = (String) token.getPrincipal();
	Map<String, Object> map = new HashMap<>(16);
	map.put("username", username);
	String password = new String((char[]) token.getCredentials());

	UserDao userMapper = ApplicationContextRegister.getBean(UserDao.class);
	// 查询用户信息
	UserDO user = userMapper.list(map).get(0);

	// 账号不存在
	if (user == null) {
		throw new UnknownAccountException("账号或密码不正确");
	}

	// 密码错误
	if (!password.equals(user.getPassword())) {
		throw new IncorrectCredentialsException("账号或密码不正确");
	}

	// 账号锁定
	if (user.getStatus() == 0) {
		throw new LockedAccountException("账号已被锁定,请联系管理员");
	}
	SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());
	return info;
}

}
3. Add shiro configuration class
@Configuration
public class ShiroConfig {

//@Autowired
//private CacheManager cacheManager;

@Value("${server.session-timeout}")
private int tomcatTimeout;

@Bean
public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
    return new LifecycleBeanPostProcessor();
}

/**
 * ShiroDialect,为了在thymeleaf里使用shiro的标签的bean
 * @return
 */

/* @Bean
public ShiroDialect shiroDialect() {
return new ShiroDialect();
}*/

@Bean
ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
	ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
	shiroFilterFactoryBean.setSecurityManager(securityManager);
	shiroFilterFactoryBean.setLoginUrl("/login");
	shiroFilterFactoryBean.setSuccessUrl("/index");

	shiroFilterFactoryBean.setUnauthorizedUrl("/403");
	LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
	filterChainDefinitionMap.put("/css/**", "anon");
	filterChainDefinitionMap.put("/js/**", "anon");
	filterChainDefinitionMap.put("/fonts/**", "anon");
	filterChainDefinitionMap.put("/img/**", "anon");
	filterChainDefinitionMap.put("/docs/**", "anon");
	filterChainDefinitionMap.put("/druid/**", "anon");
	filterChainDefinitionMap.put("/upload/**", "anon");
	filterChainDefinitionMap.put("/files/**", "anon");
	filterChainDefinitionMap.put("/logout", "logout");
	filterChainDefinitionMap.put("/", "anon");
	filterChainDefinitionMap.put("/blog", "anon");
	filterChainDefinitionMap.put("/blog/open/**", "anon");
	//filterChainDefinitionMap.put("/**", "authc");
    filterChainDefinitionMap.put("/**", "anon");

    shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
	return shiroFilterFactoryBean;
}


@Bean
public SecurityManager securityManager(EhCacheManager ehCacheManager){
    DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();
    //设置realm.
    securityManager.setRealm(userRealm());
    // 自定义缓存实现 使用redis
    securityManager.setCacheManager(ehCacheManager);
    securityManager.setSessionManager(sessionManager());
    return securityManager;
}
@Bean
public EhCacheManager ehCacheManager(CacheManager cacheManager) {
    EhCacheManager em = new EhCacheManager();
    //将ehcacheManager转换成shiro包装后的ehcacheManager对象
    em.setCacheManager(cacheManager);
    //em.setCacheManagerConfigFile("classpath:ehcache.xml");
    return em;
}
/**
 * shiro session的管理
 */
@Bean
public DefaultWebSessionManager sessionManager() {
    DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
    sessionManager.setGlobalSessionTimeout(tomcatTimeout*1000);
    //设置sessionDao对session查询,在查询在线用户service中用到了
    sessionManager.setSessionDAO(sessionDAO());
    //配置session的监听
    Collection<SessionListener> listeners = new ArrayList<SessionListener>();
    listeners.add(new BDSessionListener());
    sessionManager.setSessionListeners(listeners);
    //设置在cookie中的sessionId名称
    sessionManager.setSessionIdCookie(simpleCookie());
    return sessionManager;
}

@Bean
public SessionDAO sessionDAO(){
    return new MemorySessionDAO();
}

@Bean
public SimpleCookie simpleCookie(){

    SimpleCookie simpleCookie = new SimpleCookie();
    simpleCookie.setName("jeesite.session.id");

    return simpleCookie;
}

@Bean
UserRealm userRealm() {
	UserRealm userRealm = new UserRealm();
	return userRealm;
}

/**
 *  开启shiro aop注解支持.
 *  使用代理方式;所以需要开启代码支持;
 * @param securityManager
 * @return
 */
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
    AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
    authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
    return authorizationAttributeSourceAdvisor;
}

}
Among them:
@Bean
public EhCacheManager ehCacheManager(CacheManager cacheManager) { EhCacheManager em = new EhCacheManager(); //Convert ehcacheManager into shiro wrapped ehcacheManager object em.setCacheManager(cacheManager); //em.setCacheManagerConfigFile("classpath:ehcache .xml”); return em; } This is the cache manager org.apache.shiro.cache.ehcach.EhCacheManager that configures shiro. The parameter of the above method is to inject the cacheManager object in the spring container into EhCacheManager, so that it can be realized Shiro and cache annotations use the same caching method. The biggest misunderstanding here is the following configuration: @Bean public EhCacheManager ehCacheManager(){ EhCacheManager cacheManager = new EhCacheManager(); cacheManager.setCacheManagerConfigFile ("classpath:config/ehcache.xml"); returncacheManager; }














Be sure not to configure this way, it's just that shiro integrates ehcache cache, and it is not handed over to the spring container to manage it.

Guess you like

Origin blog.csdn.net/qq_35577329/article/details/105602809