https://blog.csdn.net/tanleijin/java/article/details/81118963
Quando springboot integrar shiro e ehcache, primeiro integre o ehcache e depois integre o shiro, para que possa ser usado diretamente quando o shiro configurar o cacheManager. Aqui estão as etapas de integração corretas: A
primeira etapa é integrar o ehcache:
1. Apresente as seguintes dependências no arquivo pom.xml
org.springframework.boot
spring-boot-starter-cache
net.sf.ehcache
ehcache
2. Apresente a configuração arquivo ehcache.xml
O conteúdo específico de 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" />
Explicação detalhada da configuração do arquivo ehcache.xml Parte das informações vem da rede diskStore: o caminho do cache, ehcache é dividido em dois níveis de memória e disco, este atributo define a localização do cache de disco. defaultCache: A estratégia de cache padrão, quando o ehcache não consegue encontrar o cache definido, esta estratégia de cache é usada. Apenas um pode ser definido. nome: nome do cache. maxElementsInMemory: o número máximo de caches maxElementsOnDisk: o número máximo de caches no disco rígido. eterno: se o objeto é permanentemente válido, uma vez definido, o tempo limite não funcionará. overflowToDisk: se deseja salvar no disco, quando o sistema está inativo timeToIdleSeconds: defina o tempo ocioso permitido (unidade: segundos) antes que o objeto expire. Utilizado apenas quando o objeto eternal = false não é permanentemente válido, um atributo opcional, o valor padrão é 0, ou seja, o tempo ocioso é infinito. timeToLiveSeconds: Defina o tempo de sobrevivência permitido (unidade: segundos) do objeto antes de expirar. O tempo máximo é entre a hora de criação e a hora de expiração. É usado apenas quando o objeto eterno = falso não é permanentemente válido, o padrão é 0. Ou seja, o tempo de vida do objeto é infinito. diskPersistent: se deve armazenar dados em cache durante o período de reinicialização da máquina virtual. Se o armazenamento de disco persistir entre as reinicializações da máquina virtual. O valor padrão é falso. diskSpoolBufferSizeMB: Este parâmetro define o tamanho do buffer de DiskStore (cache de disco). O padrão é 30 MB. Cada cache deve ter seu próprio buffer. diskExpiryThreadIntervalSeconds: O intervalo de execução de threads de falha de disco, o padrão é 120 segundos. memoryStoreEvictionPolicy: Quando o limite maxElementsInMemory é atingido, o Ehcache limpa a memória de acordo com a política especificada. A estratégia padrão é LRU (menos usada recentemente). Você pode configurá-lo para FIFO (primeiro a entrar, primeiro a sair) ou LFU (menos usado). clearOnFlush: Se deve ser limpo quando a quantidade de memória for máxima. memoryStoreEvictionPolicy: As políticas opcionais são: LRU (menos usado recentemente, política padrão), FIFO (primeiro a entrar, primeiro a sair), LFU (menos acesso). FIFO, primeiro a entrar primeiro a sair, LFU, menos usado com frequência, foi o menos usado. Conforme mencionado acima, o elemento em cache tem um atributo de ocorrência e aquele com o menor valor de ocorrência será limpo do cache. LRU, menos usado recentemente, o menos usado recentemente. O elemento em cache tem um carimbo de data / hora. Quando a capacidade do cache está cheia e você precisa abrir espaço para armazenar novos elementos em cache, o carimbo de data / hora no elemento em cache existente está diferente do horário atual. o elemento mais distante será apagado do cache. 3. Adicione a anotação de inicialização à classe principal e adicione a anotação @EnableCaching para habilitar o cache na classe principal do Spring Boot. @EnableCaching @MapperScan (basePackages = "com.tan.dream. **. Dao") @SpringBootApplication public class DreamApplication { As estratégias opcionais são: LRU (menos usado recentemente, estratégia padrão), FIFO (primeiro a entrar, primeiro a sair), LFU (menos acesso). FIFO, primeiro a entrar primeiro a sair, LFU, menos usado com frequência, foi o menos usado. Conforme mencionado acima, o elemento em cache tem um atributo de ocorrência e aquele com o menor valor de ocorrência será limpo do cache. LRU, menos usado recentemente, o menos usado recentemente. O elemento em cache tem um carimbo de data / hora. Quando a capacidade do cache está cheia e você precisa abrir espaço para armazenar novos elementos em cache, o carimbo de data / hora no elemento em cache existente está diferente do horário atual. o elemento mais distante será apagado do cache. 3. Adicione a anotação de inicialização à classe principal e adicione a anotação @EnableCaching para habilitar o cache na classe principal do Spring Boot. @EnableCaching @MapperScan (basePackages = "com.tan.dream. **. Dao") @SpringBootApplication public class DreamApplication { As estratégias opcionais são: LRU (menos usado recentemente, estratégia padrão), FIFO (primeiro a entrar, primeiro a sair), LFU (menos acesso). FIFO, primeiro a entrar primeiro a sair, LFU, menos usado com frequência, foi o menos usado. Conforme mencionado acima, o elemento em cache tem um atributo de ocorrência e aquele com o menor valor de ocorrência será limpo do cache. LRU, menos usado recentemente, o menos usado recentemente. O elemento em cache tem um carimbo de data / hora. Quando a capacidade do cache está cheia e você precisa abrir espaço para armazenar novos elementos em cache, o carimbo de data / hora no elemento em cache existente está diferente do horário atual. o elemento mais distante será apagado do cache. 3. Adicione a anotação de inicialização à classe principal e adicione a anotação @EnableCaching para habilitar o cache na classe principal do Spring Boot. @EnableCaching @MapperScan (basePackages = "com.tan.dream. **. Dao") @SpringBootApplication public class DreamApplication {
public static void main(String[] args) {
SpringApplication.run(DreamApplication.class, args);
}
} 4.
As anotações de cache @Cacheable e @CachePut em springboot podem ser usadas (o uso específico de anotações de cache a ser completado)
O foco está na segunda etapa para integrar o shiro e usar o cache ehcache:
1. Apresente as seguintes dependências no arquivo pom.xml
org.apache.shiro
shiro-spring
1.3.2
org.apache.shiro
shiro-ehcache
1.3.2
2 . Escreva a verificação do shiro Realm, claro, este é o meu reino shrio, algumas modificações precisam ser feitas de acordo com seu próprio projeto
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. Adicionar classe de configuração shiro
@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;
}
}
Entre eles:
@Bean
public EhCacheManager ehCacheManager (CacheManager cacheManager) { EhCacheManager em = new EhCacheManager (); // Converter ehcacheManager em objeto ehcacheManager embrulhado em shiro em.setCacheManager (cacheManager); //em.setCacheManagereConfigFile . ( ”); Return em; } Isso é para configurar o gerenciador de cache de shiro org.apache.shiro.cache.ehcach.EhCacheManager. O parâmetro do método acima é injetar o objeto cacheManager no container spring em EhCacheManager, para que ele possa Shiro e as anotações de cache usam o mesmo método de cache. O maior mal-entendido aqui é a seguinte configuração: @Bean public EhCacheManager ehCacheManager () { EhCacheManager cacheManager = new EhCacheManager (); cacheManager.setCacheManagerConfigFile ("classpath: config / ehcache.xml"); returncacheManager; }
Certifique-se de não configurá-lo dessa maneira, apenas que o shiro integra o cache do ehcache, não ao container do spring para gerenciá-lo.