Shiro權限管理框架(一):Shiro的基本使用

2021-01-21 java1234


作者:夜月歸途

轉載自:

https://www.cnblogs.com/guitu18/p/11258089.html

核心概念

Apache Shiro是一個強大且易用的Java安全框架,執行身份驗證、授權、密碼和會話管理。使用Shiro的易於理解的API,您可以快速、輕鬆地獲得任何應用程式,從最小的行動應用程式到最大的網絡和企業應用程式。

上面這段話來自百度百科,是不是非常官方,好像說的很明白但是又好像什麼都沒說的樣子,到底是個啥呀。想要快速理解並使用Shiro先要從最重要的三大概念入手。

Subject:大白話來講就是用戶(當然並不一定是用戶,也可以指和當前應用交互的任何對象),我們在進行授權鑑權的所有操作都是圍繞Subject(用戶)展開的,在當前應用的任何地方都可以通過SecurityUtils的靜態方法getSubject()輕鬆的拿到當前認證(登錄)的用戶。

SecurityManager:安全管理器,Shiro中最核心的組件,它管理著當前應用中所有的安全操作,包括Subject(用戶),我們圍繞Subject展開的所有操作都需要與SecurityManager進行交互。可以理解為SpringMVC中的前端控制器。

Realms:字面意思為領域,Shiro在進行權限操作時,需要從Realms中獲取安全數據,也就是用戶以及用戶的角色和權限。配置Shiro,我們至少需要配置一個Realms,用於用戶的認證和授權。通常我們的角色及權限信息都是存放在資料庫中,所以Realms也可以算是一個權限相關的Dao層,SecurityManager在進行鑑權時會從Realms中獲取權限信息。

這三個基本的概念簡答理解後就可以開始配置和使用Shiro了,其實Shiro最基本的使用非常簡單,加入依賴後只需要配置兩個Bean,再繼承一個抽象類實現兩個方法即可。

首發地址:https://www.guitu18.com/post/2019/07/26/43.html

基本使用引入一個依賴

新建一個基於Springboot的Web項目,引入Shiro依賴。

<dependency>  <groupId>org.apache.shiro</groupId>  <artifactId>shiro-spring</artifactId>  <version>1.4.0</version></dependency>


配置兩個Bean

新建一個Shiro配置類,配置Shiro最為核心的安全管理器SecurityManager。

@Beanpublic SecurityManager securityManager(UserAuthorizingRealm userRealm) {  DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();  securityManager.setRealm(userRealm);  securityManager.setRememberMeManager(null);  return securityManager;}


再配置Shiro的過濾器工廠類,將上一步配置的安全管理器注入,並配置相應的過濾規則。

@Bean    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();        shiroFilterFactoryBean.setSecurityManager(securityManager);                shiroFilterFactoryBean.setLoginUrl("/login");                Map<String, String> filterMap = new LinkedHashMap<>();                filterMap.put("/", "anon");                filterMap.put("/login", "anon");        filterMap.put("/do_login", "anon");                filterMap.put("/**", "authc");        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);        return shiroFilterFactoryBean;    }


上面使用LinkedHashMap是為了保持順序,Filter的配置順序不能隨便打亂,過濾器是按照我們配置的順序來執行的。範圍大的過濾器要放在後面,/**這條如果放在前面,那麼一來就匹配上了,就不會繼續再往後走了。這裡的對上面用到的兩個過濾器做一下簡單說明,篇幅控制其他過濾器請參閱相關文檔:

* authc:配置的url都必須認證通過才可以訪問,它是Shiro內置的一個過濾器
* 對應的實現類 @see org.apache.shiro.web.filter.authc.FormAuthenticationFilter

* anon:也是Shiro內置的,它對應的過濾器裡面是空的,什麼都沒做,可以理解為不攔截
* 對應的實現類 @see org.apache.shiro.web.filter.authc.AnonymousFilter

實現兩個方法

在上一步的安全管理器配置中,我們通過形參注入了一個UserAuthorizingRealm對象,這個就是認證和授權相關的流程,需要我們自己實現。繼承AuthorizingRealm之後,我們需要實現兩個抽象方法,一個是認證,一個是授權,這兩個方法長得很像,別弄混淆了。

doGetAuthenticationInfo():認證。相當於登錄,只有通過登錄了,才能進行後面授權的操作。一些只需要登錄權限的操作,在登錄成功後就可以訪問了,比如上一步中配置的authc過濾器就是只需要登錄權限的。

doGetAuthorizationInfo():授權。認證過後,僅僅擁有登錄權限,更多細粒度的權限控制,比如菜單權限,按鈕權限,甚至方法調用權限等,都可以通過授權輕鬆實現。在這個方法裡,我們可以拿到當前登錄的用戶,再根據實際業務賦予用戶部分或全部權限,當然這裡也可以賦予用戶某些角色,後面也可以根據角色鑑權。下方的演示代碼僅添加了權限,賦予角色可以調用addRoles()或者setRoles()方法,傳入角色集合。

public class UserAuthorizingRealm extends AuthorizingRealm {
@Autowired private LoginService loginService;
@Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { User user = (User) principalCollection.getPrimaryPrincipal(); List<String> perms; if (User.SUPER_ADMIN == user.getId()) { perms = loginService.getAllPerms(); } else { perms = loginService.getUserPerms(user.getId()); }
Set<String> permsSet = new HashSet<>(); for (String perm : perms) { permsSet.addAll(Arrays.asList(perm.trim().split(","))); }
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.setStringPermissions(permsSet); return info; }
@Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; User user = loginService.getUserByUsername(token.getUsername()); if (user == null) { throw new UnknownAccountException("帳號或密碼不正確"); } if (user.getStatus() == null || user.getStatus() == 1) { throw new LockedAccountException("帳號已被鎖定,請聯繫管理員"); } if (!user.getPassword().equals(new String(token.getPassword()))) { throw new UnknownAccountException("帳號或密碼不正確"); } user.setSessionId(SecurityUtils.getSubject().getSession().getId().toString()); user.setLastLoginTime(new Date()); return new SimpleAuthenticationInfo(user, user.getPassword(), getName()); }}


這樣配置完成以後,就可以基於URL做粗粒度的權限控制了,我們可以通過不同的過濾器為URL配置不同的權限。

Shiro提供了很多內置的過濾器,我們最常用的就是第一個和第二個。如果對其效果不滿意,我們還可以自定義過濾器實現權限控制。
文檔地址:http://shiro.apache.org/web.html#default-filters

細粒度權限控制

如果需要更細緻的權限控制,請繼續往下添加配置,可以做到方法級別的權限控制。其實在SpringMVC中URL也能做到方法級別控制,但是使用URL來控制方法級別的權限配置起來簡直反人類,通常URL權限控制通常都是泛解析,做通用的權限配置,比如後臺管理的/admin/**這種需要登錄權限的。在實際開發中註解式的權限控制用的最多。

AdvisorAutoProxyCreator

註解式的權限控制需要配置兩個Bean,第一個是AdvisorAutoProxyCreator,代理生成器,需要藉助SpringAOP來掃描@RequiresRoles和@RequiresPermissions等註解,生成代理類實現功能增強,從而實現權限控制。需要配合AuthorizationAttributeSourceAdvisor一起使用,否則權限註解無效。

@Beanpublic DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {  DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();  autoProxyCreator.setProxyTargetClass(true);  return autoProxyCreator;}


AuthorizationAttributeSourceAdvisor

上面配置的DefaultAdvisorAutoProxyCreator相當於一個切面,下面這個類就相當於切點了,兩個一起才能實現註解權限控制。

@Beanpublic AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {  AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();  advisor.setSecurityManager(securityManager);  return advisor;}

配置完上面兩個Bean之後我們就可以使用註解來控制權限了,Shiro中的權限註解有很多,我們最常用的其實就兩個,@RequiresRoles和@RequiresPermissions,前者是角色驗證,後者是權限驗證。他們都可以傳入兩個參數,value是必須的,可以傳入一個字符數組,表示一個或多個角色(權限),另一個參數logical有兩個值可選,AND和OR,默認為AND,表示這組角色(權限)是必須都有還是僅需要一個就能訪問。

舉個慄子:

@RequestMapping("getLoginUserInfo")@RequiresPermissions(value = {"user:list", "user:info"}, logical = Logical.OR)public JsonResult getLoginUserInfo() {  Subject subject = SecurityUtils.getSubject();  User user = (User) subject.getPrincipal();  return JsonResult.ok(user);}

以上代碼表示getLoginUserInfo()方法需要當前登錄用戶擁有user:list或者user:list權限才能訪問。

最後放上項目代碼,其實代碼是很早之前的,今天才做的筆記而已。

Gitee:https://gitee.com/guitu18/ShiroDemo

GitHub:https://github.com/guitu18/ShiroDemo

本篇結束,Shiro的使用還是非常簡單的。下一篇,準備記錄一下基於Springboot和Shiro使用Redis實現集群環境的Session共享,以實現單點登錄。


長按關注鋒哥微信公眾號,非常感謝;



相關焦點

  • Shiro 權限校驗分析
    Shiro 概述Shiro 是一款 Apache 提供的權限校驗框架, Shiro 同時也是一個強大且易用的 Java 安全框架,執行身份驗證、授權、密碼學和會話管理。使用 Shiro 的易於理解的 API,您可以快速、輕鬆地獲得任何應用程式,從最小的行動應用程式到最大的網絡和企業應用程式,特別是今天對權限校驗和管理特別嚴格,大家有必要對shiro 有一個基本的認識和學習。
  • Shiro入門這篇就夠了【Shiro的基礎知識、回顧URL攔截】
    前言本文主要講解的知識點有以下:權限管理的基礎知識回顧URL攔截的實現Shiro的介紹與簡單入門一、Shiro基礎知識在學習Shiro這個框架之前,首先我們要先了解Shiro需要的基礎知識:權限管理1.1什麼是權限管理?
  • mall改造:自定義註解和shiro權限結合,解放生產力
    這次我們聊一聊litemall中的shiro和自定義註解的組合通過上面的介紹,我們可以得知,litemall本次採用的方式,是沒有將前端與按鈕的權限一起放到資料庫中,而是將前端的頁面和權限和按鈕權限,通過註解的方式獲取。
  • 30 分鐘學會如何使用 Shiro
    要學習如何使用Shiro必須先從它的架構談起,作為一款安全框架Shiro的設計相當精妙。Shiro的應用不依賴任何容器,它也可以在JavaSE下使用。但是最常用的環境還是JavaEE。用戶具有角色和權限兩種最基本的屬性。例如,我的Windows登陸名稱是learnhow,它的角色是administrator,而administrator具有所有系統權限。這樣learnhow自然就擁有了所有系統權限。那麼其他人需要登錄我的電腦怎麼辦,我可以開放一個guest角色,任何無法提供正確用戶名與密碼的未知用戶都可以通過guest來登錄,而系統對於guest角色開放的權限極其有限。
  • 「網絡安全」關於Apache Shiro權限繞過高危漏洞的 預警通報
    近日,國家信息安全漏洞共享平臺(CNVD)公布了深信服終端檢測平臺(EDR)遠程命令執行高危漏洞,攻擊者利用該漏洞可遠程執行系統命令,獲得目標伺服器的權限。一、漏洞情況Apache Shiro是一個強大且易用的Java安全框架,用於執行身份驗證、授權、密碼和會話管理。
  • Apache Shiro反序化識別那些事
    1.1 關於Apache ShiroApache shiro是一個Java安全框架,提供了認證、授權、加密和會話管理功能,為解決應安全提供了相應的API:1.認證-用戶身份識別,常被稱為用戶」登錄」>Shiro550:shiro≤1.2.4版本,默認使CookieRememberMeManager,由於AES使用的key洩露,導致反序化的cookie可控,從而引發反序化攻擊。
  • 30分鐘學會如何使用Shiro,看這篇文章就夠了!
    一、架構要學習如何使用Shiro必須先從它的架構談起,作為一款安全框架Shiro的設計相當精妙。Shiro的應用不依賴任何容器,它也可以在JavaSE下使用。但是最常用的環境還是JavaEE。用戶具有角色和權限兩種最基本的屬性。例如,我的Windows登陸名稱是learnhow,它的角色是administrator,而administrator具有所有系統權限。這樣learnhow自然就擁有了所有系統權限。那麼其他人需要登錄我的電腦怎麼辦,我可以開放一個guest角色,任何無法提供正確用戶名與密碼的未知用戶都可以通過guest來登錄,而系統對於guest角色開放的權限極其有限。
  • Shiro整合redis
    在實際落地過程中,會發現如果出現集群部署服務,那麼單個服務的shiro無法認證另一個服務下面的session.
  • Spring Boot與Shiro整合實現用戶認證
    使用Shiro內置過濾器實現頁面攔截package com.itheima.shiro;import java.util.LinkedHashMap;import java.util.Map;import org.apache.shiro.spring.web.ShiroFilterFactoryBean
  • 聽歌學日語886~SUPER SHIRO
    專輯:SUPER SHIRO作曲 : 溝渕大智作詞 : 市川喜康編曲:溝渕大智君(きみ)は super shiro你就是超級小白実(じつ)は super hero其實是超級英雄わたあめフワフワ ベイベー柔軟得像棉花糖平和(へいわ)を守(ま)ってる守護和平的使者君(きみ)は super shiro你就是超級小白おなか空(あ)いても就算肚子空空世界(
  • 實戰,通過複寫shiro的SessionDAO來實現將session保存到redis集群中
    現在通用的做法就是使用redis、memcached等組件獨立存儲所有應用節點的Session,以達到各個應用節點之間的Session共享的目的在Java Web項目中實現session共享的一個很好的解決方案是:Spring Session+Spring Data Redis。
  • 披著小眾化外衣的shiro 如何做著「大眾化」生意?
    shiro就是在這塊美好的土地所誕生的品牌。公司於1989年所創立,2000年後才開始漸漸從土產轉換為護膚品。不過,品牌一開始並不叫shiro,先在2009年正式成立了品牌LAUREL之後,再在2015年決定進軍海外,才把名字改為shiro。
  • 高版本AES-GCM模式加密的Shiro漏洞利用
    ) print(plaintext) base64_plaintext=base64.b64encode(plaintext).decode() print ("\nbase64_plaintext:\n"+base64_plaintext+"\n") return base64_plaintext加密腳本設定加密模式為aes-gcm,隨機生成16位iv,使用
  • 「計算機畢設」基於springboot開發倉庫管理系統
    基於Springboot開發的倉庫管理系統,底層權限控制已經基於shiro實現了,直接可以作為二次開發框架使用!使用技術本套系統採用的是springboot、mybatisPlus、shiro、layui開發而成,都屬於現在比較流行的技術!看懂這個源碼絕大部分項目都能夠輕鬆應對!
  • 美妝鑑定:徐璐安利同款shiro身體乳真假鑑定
    shiro身體乳是白色乳液狀質地,非常水潤,很好推開,一抹即被肌膚吸收了。使用之後不會感覺到粘膩,非常清爽,可以感覺到塗抹部位有一層薄薄的膜在保護肌膚。而且持香時間可長達 15 小時。接下來就分享幾個真假鑑定小知識。
  • Spring Boot+Maven+JPA+Shiro+Easyui實現通用用戶權限管理系統
    項目描述日常工作中,權限管理是管理系統必不可少的功能。網絡上有各種各樣的權限管理系統,不過用別人的總不如自己寫一套來得踏實。之前本菜鳥分享的例子裡有各種技術點的分項實例,這次做一個綜合,形成自己的簡單通用的權限管理系統。