Shiro权限管理框架
Shiro
一. Shiro權(quán)限
- 什么是權(quán)限控制:
- 忽略特別細的概念,比如權(quán)限能細分很多種,功能權(quán)限,數(shù)據(jù)權(quán)限,管理權(quán)限等
- 理解兩個概念:用戶和資源,讓指定的用戶,只能操作指定的資源(CRUD)
- 初學javaweb時怎么做
- Filter接口中有一個doFilter方法,自己編寫好業(yè)務Filter,并配置對哪個web資源進行攔截后
- 如果訪問的路徑命中對應的Filter,則會執(zhí)行doFilter()方法,然后判斷是否有權(quán)限進行訪問對應的資源
- /api/user/info?id=1
二. 權(quán)限框架ACL和RBAC
2.1 什么是ACL和RBAC
-
ACL: Access Control List 訪問控制列表
- 以前盛行的一種權(quán)限設計,它的核心在于用戶直接和權(quán)限掛鉤
- 優(yōu)點:簡單易用,開發(fā)便捷
- 缺點:用戶和權(quán)限直接掛鉤,導致在授予時的復雜性,比較分散,不便于管理
- 例子:常見的文件系統(tǒng)權(quán)限設計, 直接給用戶加權(quán)限
-
RBAC: Role Based Access Control
- 基于角色的訪問控制系統(tǒng)。權(quán)限與角色相關聯(lián),用戶通過成為適當角色的成員而得到這些角色的權(quán)限
- 優(yōu)點:簡化了用戶與權(quán)限的管理,通過對用戶進行分類,使得角色與權(quán)限關聯(lián)起來
- 缺點:開發(fā)對比ACL相對復雜
- 例子:基于RBAC模型的權(quán)限驗證框架與應用 Apache Shiro、spring Security
-
BAT企業(yè) ACL,一般是對報表系統(tǒng),阿里的ODPS
-
總結(jié):不能過于復雜,規(guī)則過多,維護性和性能會下降, 更多分類 ABAC、PBAC等
2.2 主流權(quán)限框架介紹和技術(shù)選型講解
-
什么是 spring Security:官網(wǎng)基礎介紹
- 官網(wǎng):https://spring.io/projects/spring-security
-
什么是 Apache Shiro:官網(wǎng)基礎介紹
-
https://github.com/apache/shiro
Apache Shiro是一個強大且易用的Java安全框架,執(zhí)行身份驗證、授權(quán)、密碼和會話管理。使用Shiro的易于理解的API,您可以快速、輕松地獲得任何應用程序,從最小的移動應用程序到最大的網(wǎng)絡和企業(yè)應用程序。一句話:Shiro是一個強大易用的Java安全框架,提供了認證、授權(quán)、加密和會話管理等功能
-
-
兩個優(yōu)缺點,應該怎么選擇
-
Apache Shiro比Spring Security , 前者使用更簡單
-
Shiro 功能強大、 簡單、靈活, 不跟任何的框架或者容器綁定,可以獨立運行
-
Spring Security 對Spring 體系支持比較好,脫離Spring體系則很難開發(fā)
-
SpringSecutiry 支持Oauth鑒權(quán) https://spring.io/projects/spring-security-oauth,Shiro需要自己實現(xiàn)
-
三. Apache Shiro基礎概念和架構(gòu)
3.1 Shiro核心知識之架構(gòu)圖交互和四大模塊
- 直達Apache Shiro官網(wǎng) http://shiro.apache.org/introduction.html
- 什么是身份認證
- Authentication,身份證認證,一般就是登錄
- 什么是授權(quán)
- Authorization,給用戶分配角色或者訪問某些資源的權(quán)限
- 什么是會話管理
- Session Management, 用戶的會話管理員,多數(shù)情況下是web session
- 什么是加密
- Cryptography, 數(shù)據(jù)加解密,比如密碼加解密等
3.2 Shrio權(quán)限控制流程和概念
- Subject
- 我們把用戶或者程序稱為主體(如用戶,第三方服務,cron作業(yè)),主體去訪問系統(tǒng)或者資源
- SecurityManager
- 安全管理器,Subject的認證和授權(quán)都要在安全管理器下進行
- Authenticator
- 認證器,主要負責Subject的認證
- Realm
- 數(shù)據(jù)域,Shiro和安全數(shù)據(jù)的連接器,好比jdbc連接數(shù)據(jù)庫; 通過realm獲取認證授權(quán)相關信息
- Authorizer
- 授權(quán)器,主要負責Subject的授權(quán), 控制subject擁有的角色或者權(quán)限
- Cryptography
- 加解密,Shiro的包含易于使用和理解的數(shù)據(jù)加解密方法,簡化了很多復雜的api
- Cache Manager
- 緩存管理器,比如認證或授權(quán)信息,通過緩存進行管理,提高性能
更多資料導航:http://shiro.apache.org/reference.html
四. Spring boot整合Shiro
4.1 依賴
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId> </dependency> <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope> </dependency> <dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId> </dependency> <dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.4.1</version> </dependency><!-- mybatis分頁支持 --> <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.2.12</version> </dependency><!-- tk.mybatis對mybatis做了二次封裝--> <dependency><groupId>tk.mybatis</groupId><artifactId>mapper</artifactId><version>4.1.5</version> </dependency><!-- tk.mybatis與spring boot整合 --> <dependency><groupId>tk.mybatis</groupId><artifactId>mapper-spring-boot-starter</artifactId><version>2.1.5</version> </dependency>4.2 數(shù)據(jù)庫表的設計
權(quán)限標準五張表:
- sys_user
- sys_role
- sys_user_role
- sys_permission
- sys_role_permission
4.3 自定義realm
public class CustomRealm extends AuthorizingRealm {/*** 進行權(quán)限校驗的時候回調(diào)用*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals){SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();return simpleAuthorizationInfo;}/*** 用戶登錄的時候會調(diào)用*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {return new SimpleAuthenticationInfo(username, user.getPassword(), this.getClass().getName());} }4.3 shiro配置
@Configuration public class ShiroConfig {@Beanpublic ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager){ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();shiroFilterFactoryBean.setSecurityManager(securityManager);shiroFilterFactoryBean.setLoginUrl("/no_login");shiroFilterFactoryBean.setUnauthorizedUrl("/no_auth");Map<String, String> chainFilter = new LinkedHashMap<>();chainFilter.put("/login", "anon"); //允許登錄chainFilter.put("/**", "authc");shiroFilterFactoryBean.setFilterChainDefinitionMap(chainFilter);return shiroFilterFactoryBean;}/*** 該類的作用是,實現(xiàn)注解的方式來設置權(quán)限*/@Beanpublic DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){DefaultAdvisorAutoProxyCreator advisor = new DefaultAdvisorAutoProxyCreator();advisor.setProxyTargetClass(true);return advisor;}/*** 實現(xiàn)注解的方式來配置權(quán)限*/@Beanpublic AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);return authorizationAttributeSourceAdvisor;}/**@Beanpublic LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {return new LifecycleBeanPostProcessor();}*//*** SecurityManager的配置*/@Beanpublic SecurityManager securityManager(SessionManager manager, Realm realm) {DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();securityManager.setSessionManager(sessionManager);securityManager.setRealm(realm);return securityManager;}/*** SessionManager的配置*/@Beanpublic SessionManager sessionManager(){SessionManager sessionManager = new CustomSessionManager();return sessionManager;}/*** Realm* @param addSaltCredentialsMatch* @return*/@Beanpublic Realm realm(AddSaltCredentialsMatch addSaltCredentialsMatch) {CustomRealm realm = new CustomRealm();realm.setCredentialsMatcher(addSaltCredentialsMatch); //密碼規(guī)則return realm;}/*** 自定義的密碼加鹽規(guī)則* @return*/@Beanpublic AddSaltCredentialsMatch addSaltCredentialsMatch() {return new AddSaltCredentialsMatch();} }4.4 自定義SessionManager
public class CustomSessionManager extends DefaultWebSessionManager {/*** 重寫默認的session* @param request* @param response* @return*/@Overrideprotected Serializable getSessionId(ServletRequest request, ServletResponse response) {String sessionId = WebUtils.toHttp(request).getHeader("token");if(null != sessionId) {request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,ShiroHttpServletRequest.COOKIE_SESSION_ID_SOURCE);request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, sessionId);//automatically mark it valid here. If it is invalid, the//onUnknownSession method below will be invoked and we'll remove the attribute at that time.request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);return sessionId;}else {return super.getSessionId(request, response);}} }五. 權(quán)限數(shù)據(jù)緩存
? redis作為企業(yè)使用最為頻繁的中間件,用來緩存各種業(yè)務數(shù)據(jù),在使用shiro的緩存的時候,課程中還是采用redis來作為緩存中間件。下載地址:https://github.com/MicrosoftArchive/redis/releases
5.1 引入依賴
<dependency><groupId>org.crazycake</groupId><artifactId>shiro-redis</artifactId><version>3.2.3</version> </dependency>5.2 配置RedisManager
@Bean public RedisManager redisManager() {RedisManager redisManager = new RedisManager();redisManager.setHost("localhost:6379");return redisManager; }5.3 配置CacheManager
@Bean public CacheManager cacheManager(RedisManager redisManager) {RedisCacheManager cacheManager = new RedisCacheManager();cacheManager.setRedisManager(redisManager);return cacheManager; }5.4 在SecurityManager中加入緩存管理
securityManager.setCacheManager(cacheManager);六. Session數(shù)據(jù)的緩存
6.1 配置RedisSessionDao
@Bean public RedisSessionDAO redisSessionDAO(RedisManager redisManager) {RedisSessionDAO redisSessionDAO = new RedisSessionDAO();redisSessionDAO.setRedisManager(redisManager);return redisSessionDAO; }6.2 SessionManager的設置
@Bean public SessionManager sessionManager(RedisSessionDAO redisSessionDAO){CustomSessionManager sessionManager = new CustomSessionManager();sessionManager.setSessionDAO(redisSessionDAO);return sessionManager; }附錄:
/**shiro內(nèi)部提供了做兩次md5處理。但是得到數(shù)據(jù)與其他工具類,得到兩次md5數(shù)據(jù)不一致。*/ @Bean public CredentialsMatcher credentialsMatcher() {HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();hashedCredentialsMatcher.setHashAlgorithmName("MD5"); //設置加密方式hashedCredentialsMatcher.setHashIterations(2); //作兩次md5加密return hashedCredentialsMatcher; }處理方式:在用戶注冊的時候,存入密碼的時候就按照shiro的規(guī)則來儲存密碼。
new SimpleHash("md5", "123", null, 2).toString() // 將這種處理方式得到的密碼存入數(shù)據(jù)庫。總結(jié)
以上是生活随笔為你收集整理的Shiro权限管理框架的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python实现比较两手牌的大小--斗地
- 下一篇: 国家普通话智能测试软件,国家普通话水平智