shiro原理_java:shiro高级篇——1
生活随笔
收集整理的這篇文章主要介紹了
shiro原理_java:shiro高级篇——1
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
第六章 Realm緩存機制
1、Realm緩存機制意義
在上面我們自定了自己的realm,但是我們發現
在認證和授權的時候,程序需要頻繁的訪問數據庫,這樣對于數據庫的壓力可想而知,那我們怎么處理呢?
2、Realm緩存機制實現思路
【1】緩存機制圖解
【2】原理分析
此時我們對UserBridgeServiceImpl的實現類里面的邏輯加入了自定義的SimpleCacheService緩存服務接口,簡單來說實現了在認證和鑒權時不需要每次都去查詢數據庫,而是把認證和鑒權信息放入到redis緩存中,以減低數據庫的訪問壓力
1、集成redis服務器,作為集中存儲認證和鑒權信息 2、改寫UserBridgeServiceImpl使其優先從緩存中讀取
3、redission集成
【1】添加ShiroRedisProperties
此類主要負責yaml文件的配置類
package com.itheima.shiro.config;import lombok.Data;import org.springframework.boot.context.properties.ConfigurationProperties;import java.io.Serializable;/** * @Description redis配置文件 */@Data@ConfigurationProperties(prefix = "itheima.framework.shiro.redis")public class ShiroRedisProperties implements Serializable { /** * redis連接地址 */ private String nodes ; /** * 獲取連接超時時間 */ private int connectTimeout ; /** * 連接池大小 */ private int connectPoolSize; /** * 初始化連接數 */ private int connectionMinimumidleSize ; /** * 等待數據返回超時時間 */ private int timeout ; /** * 全局超時時間 */ private long globalSessionTimeout;}【2】編輯ShiroConfig
集成redisson的相關配置,同時啟用ShiroRedisProperties的配置
package com.itheima.shiro.config;import com.itheima.shiro.core.ShiroDbRealm;import com.itheima.shiro.core.impl.ShiroDbRealmImpl;import com.itheima.shiro.filter.RolesOrAuthorizationFilter;import com.itheima.shiro.properties.PropertiesUtil;import lombok.extern.log4j.Log4j2;import org.apache.shiro.spring.LifecycleBeanPostProcessor;import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;import org.apache.shiro.spring.web.ShiroFilterFactoryBean;import org.apache.shiro.web.mgt.DefaultWebSecurityManager;import org.apache.shiro.web.servlet.SimpleCookie;import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;import org.redisson.Redisson;import org.redisson.api.RedissonClient;import org.redisson.config.Config;import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.context.properties.EnableConfigurationProperties;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.DependsOn;import javax.servlet.Filter;import java.util.HashMap;import java.util.LinkedHashMap;import java.util.List;import java.util.Map;/** * @Description 權限配置類 */@Configuration@ComponentScan(basePackages = "com.itheima.shiro.core")@EnableConfigurationProperties({ShiroRedisProperties.class})@Log4j2public class ShiroConfig { @Autowired private ShiroRedisProperties shiroRedisProperties; /** * @Description redission客戶端 */ @Bean("redissonClientForShiro") public RedissonClient redissonClient() { log.info("=====初始化redissonClientForShiro開始======"); String[] nodeList = shiroRedisProperties.getNodes().split(","); Config config = new Config(); if (nodeList.length == 1) { config.useSingleServer().setAddress(nodeList[0]) .setConnectTimeout(shiroRedisProperties.getConnectTimeout()) .setConnectionMinimumIdleSize(shiroRedisProperties.getConnectionMinimumidleSize()) .setConnectionPoolSize(shiroRedisProperties.getConnectPoolSize()).setTimeout(shiroRedisProperties.getTimeout()); } else { config.useClusterServers().addNodeAddress(nodeList) .setConnectTimeout(shiroRedisProperties.getConnectTimeout()) .setMasterConnectionMinimumIdleSize(shiroRedisProperties.getConnectionMinimumidleSize()) .setMasterConnectionPoolSize(shiroRedisProperties.getConnectPoolSize()).setTimeout(shiroRedisProperties.getTimeout()); } RedissonClient redissonClient = Redisson.create(config); log.info("=====初始化redissonClientForShiro完成======"); return redissonClient; } /** * @Description 創建cookie對象 */ @Bean(name="sessionIdCookie") public SimpleCookie simpleCookie(){ SimpleCookie simpleCookie = new SimpleCookie(); simpleCookie.setName("ShiroSession"); return simpleCookie; } /** * @Description 權限管理器 * @param * @return */ @Bean(name="securityManager") public DefaultWebSecurityManager defaultWebSecurityManager(){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(shiroDbRealm()); securityManager.setSessionManager(shiroSessionManager()); return securityManager; } /** * @Description 自定義RealmImpl */ @Bean(name="shiroDbRealm") public ShiroDbRealm shiroDbRealm(){ return new ShiroDbRealmImpl(); } /** * @Description 會話管理器 */ @Bean(name="sessionManager") public DefaultWebSessionManager shiroSessionManager(){ DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); sessionManager.setSessionValidationSchedulerEnabled(false); sessionManager.setSessionIdCookieEnabled(true); sessionManager.setSessionIdCookie(simpleCookie()); sessionManager.setGlobalSessionTimeout(3600000); return sessionManager; } /** * @Description 保證實現了Shiro內部lifecycle函數的bean執行 */ @Bean(name = "lifecycleBeanPostProcessor") public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } /** * @Description AOP式方法級權限檢查 */ @Bean @DependsOn("lifecycleBeanPostProcessor") public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); defaultAdvisorAutoProxyCreator.setProxyTargetClass(true); return defaultAdvisorAutoProxyCreator; } /** * @Description 配合DefaultAdvisorAutoProxyCreator事項注解權限校驗 */ @Bean public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor() { AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor(); aasa.setSecurityManager(defaultWebSecurityManager()); return new AuthorizationAttributeSourceAdvisor(); } /** * @Description 過濾器鏈 */ private Map filterChainDefinition(){ List list = PropertiesUtil.propertiesShiro.getKeyList(); Map map = new LinkedHashMap<>(); for (Object object : list) { String key = object.toString(); String value = PropertiesUtil.getShiroValue(key); log.info("讀取防止盜鏈控制:---key{},---value:{}",key,value); map.put(key, value); } return map; } /** * @Description 自定義過濾器定義 */ private Map filters() { Map map = new HashMap(); map.put("roleOr", new RolesOrAuthorizationFilter()); return map; } /** * @Description Shiro過濾器 */ @Bean("shiroFilter") public ShiroFilterFactoryBean shiroFilterFactoryBean(){ ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean(); shiroFilter.setSecurityManager(defaultWebSecurityManager()); //使自定義過濾器生效 shiroFilter.setFilters(filters()); shiroFilter.setFilterChainDefinitionMap(filterChainDefinition()); shiroFilter.setLoginUrl("/login"); shiroFilter.setUnauthorizedUrl("/login"); return shiroFilter; }}4、緩存對象SimpleMapCache
package com.itheima.shiro.core.base;import com.itheima.shiro.utils.EmptyUtil;import org.apache.shiro.cache.Cache;import org.apache.shiro.cache.CacheException;import java.io.Serializable;import java.util.Collection;import java.util.Collections;import java.util.Map;import java.util.Set;/** * @Description 緩存實現類, 實現序列 接口方便對象存儲于第三方容器(Map存放鍵值對) */public class SimpleMapCache implements Cache, Serializable { private final Map attributes; private final String name; public SimpleMapCache(String name, Map backingMap) { if (name == null) throw new IllegalArgumentException("Cache name cannot be null."); if (backingMap == null) { throw new IllegalArgumentException("Backing map cannot be null."); } else { this.name = name; attributes = backingMap; } } public Object get(Object key) throws CacheException { return attributes.get(key); } public Object put(Object key, Object value) throws CacheException { return attributes.put(key, value); } public Object remove(Object key) throws CacheException { return attributes.remove(key); } public void clear() throws CacheException { attributes.clear(); } public int size() { return attributes.size(); } public Set keys() { Set keys = attributes.keySet(); if (!keys.isEmpty()) return Collections.unmodifiableSet(keys); else return Collections.emptySet(); } public Collection values() { Collection values = attributes.values(); if (!EmptyUtil.isNullOrEmpty(values)) return Collections.unmodifiableCollection(values); else return Collections.emptySet(); } @Override public String toString() { return "SimpleMapCache [attributes=" + attributes + ", name=" + name + ", keys()=" + keys() + ", size()=" + size() + ", values()=" + values() + "]"; }}5、ShiroRedissionSerialize序列化工具
package com.itheima.shiro.utils;import lombok.extern.log4j.Log4j2;import org.apache.shiro.codec.Base64;import java.io.*;/** * @Description:實現shiro會話的序列化存儲 */@Log4j2public class ShiroRedissionSerialize { public static Object deserialize(String str) { if (EmptyUtil.isNullOrEmpty(str)) { return null; } ByteArrayInputStream bis = null; ObjectInputStream ois = null; Object object=null; try { bis = new ByteArrayInputStream(EncodesUtil.decodeBase64(str)); ois = new ObjectInputStream(bis); object = ois.readObject(); } catch (IOException |ClassNotFoundException e) { log.error("流讀取異常:{}",e); } finally { try { bis.close(); ois.close(); } catch (IOException e) { log.error("流讀取異常:{}",e); } } return object; } public static String serialize(Object obj) { if (EmptyUtil.isNullOrEmpty(obj)) { return null; } ByteArrayOutputStream bos = null; ObjectOutputStream oos = null; String base64String = null; try { bos = new ByteArrayOutputStream(); oos = new ObjectOutputStream(bos); oos.writeObject(obj); base64String = EncodesUtil.encodeBase64(bos.toByteArray()); } catch (IOException e) { log.error("流寫入異常:{}",e); } finally { try { bos.close(); oos.close(); } catch (IOException e) { log.error("流寫入異常:{}",e); } } return base64String; }}6、緩存服務接口SimpleCacheService
SimpleCacheService
package com.itheima.shiro.core;import org.apache.shiro.cache.Cache;import org.apache.shiro.cache.CacheException;/** * @Description 簡單的緩存管理接口 */public interface SimpleCacheService { /** * 功能說明::新增緩存堆到管理器*/ void createCache(String cacheName, Cache cache) throws CacheException; /** * 方法名::getCache
* 功能說明::獲取緩存堆
*/ Cache getCache(String cacheName) throws CacheException; /** * 方法名::removeCache
* 功能說明::移除緩存堆
*/ void removeCache(String cacheName) throws CacheException; /** * 方法名::updateCahce
* 功能說明::更新緩存堆
*/ void updateCahce(String cacheName, Cache cache) throws CacheException;}
SimpleCacheServiceImpl
調用RedissonClient去實現緩存,同時使用ShiroRedissionSerialize實現序列化
package com.itheima.shiro.core.impl;import com.itheima.shiro.constant.CacheConstant;import com.itheima.shiro.core.SimpleCacheService;import com.itheima.shiro.utils.ShiroRedissionSerialize;import lombok.extern.log4j.Log4j2;import org.apache.shiro.SecurityUtils;import org.apache.shiro.cache.Cache;import org.apache.shiro.cache.CacheException;import org.redisson.api.RBucket;import org.redisson.api.RedissonClient;import org.springframework.stereotype.Component;import javax.annotation.Resource;import java.util.concurrent.TimeUnit;/** * * @Description 簡單的緩存管理接口的實現 */@Log4j2@Componentpublic class SimpleCacheServiceImpl implements SimpleCacheService { @Resource(name = "redissonClientForShiro") RedissonClient redissonClient; @Override public void createCache(String name, Cache cache){ RBucket bucket = redissonClient.getBucket(CacheConstant.GROUP_CAS+name); bucket.trySet(ShiroRedissionSerialize.serialize(cache), SecurityUtils.getSubject().getSession().getTimeout()/1000, TimeUnit.SECONDS); } @SuppressWarnings("unchecked") @Override public Cache getCache(String name) throws CacheException { RBucket bucket = redissonClient.getBucket(CacheConstant.GROUP_CAS+name); return (Cache) ShiroRedissionSerialize.deserialize(bucket.get()); } @Override public void removeCache(String name) throws CacheException { RBucket bucket = redissonClient.getBucket(CacheConstant.GROUP_CAS+name); bucket.delete(); } @Override public void updateCahce(String name, Cache cache){ RBucket bucket = redissonClient.getBucket(CacheConstant.GROUP_CAS+name); bucket.set(ShiroRedissionSerialize.serialize(cache), SecurityUtils.getSubject().getSession().getTimeout()/1000, TimeUnit.MILLISECONDS); }}總結
以上是生活随笔為你收集整理的shiro原理_java:shiro高级篇——1的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: springcloud 组件_深入理解
- 下一篇: latex 伪代码_Latex-算法伪代