Shiro 權限校驗分析

2020-12-22 黑馬程式設計師

Shiro 概述

Shiro 是一款 Apache 提供的權限校驗框架, Shiro 同時也是一個強大且易用的 Java 安全框架,執行身份驗證、授權、密碼學和會話管理。使用 Shiro 的易於理解的 API,您可以快速、輕鬆地獲得任何應用程式,從最小的行動應用程式到最大的網絡和企業應用程式,特別是今天對權限校驗和管理特別嚴格,大家有必要對shiro 有一個基本的認識和學習。

Shiro 的三大核心組件

1、Subject :當前用戶的操作

2、SecurityManager:用於管理所有的 Subject 3、Realms:用於進行權限信息的驗證

如下圖:各組件之間的調用關係:

Subject:翻譯為主角,當前參與應用安全部分的主角。可以是用戶,可以試第三方服務,可以是 cron 任務,或者任何東西。主要指一個正在與當前軟體交互的東西。所有 Subject 都需要 SecurityManager,當你與 Subject 進行交互,這些交互行為實際上被轉換為與 SecurityManager 的交互

SecurityManager:安全管理員,Shiro 架構的核心,它就像 Shiro 內部所有原件的保護傘。然而一旦配置了 SecurityManager,SecurityManager 就用到的比較少,開發者大部分時間都花在 Subject 上面請記得,當你與 Subject 進行

交互的時候,實際上是 SecurityManager 在背後幫你舉起 Subject 來做一些安全操作。

Realms:Realms 作為 Shiro 和你的應用的連接橋,當需要與安全數據交互的時候,像用戶帳戶,或者訪問控制,Shiro 就從一個或多個 Realms 中查找。Shiro 提供了一些可以直接使用的 Realms,如果默認的 Realms 不能滿足你的需求,你也可以定製自己的 Realms.

Shiro 的十大功能特點:

功能特點

Shiro 包含 10 個內容,如下圖:

Authentication:身份認證/登錄,驗證用戶是不是擁有相應的身份。Authorization:授權,即權限驗證,驗證某個已認證的用戶是否擁有某個權限; 即判斷用戶是否能做事情,常見的如:驗證某個用戶是否擁有某個角色。或者細粒度的驗證某個用戶對某個資源是否具有某個權限。Session Manager:會話管理,即用戶登錄後就是一次會話,在沒有退出之前,它的所有信息都在會話中;會話可以是普通 JavaSE 環境的,也可以是如 Web 環境的。Cryptography:加密,保護數據的安全性,如密碼加密存儲到資料庫,而不是明文存儲。Web Support:Web 支持,可以非常容易的集成到 web 環境。Caching:緩存,比如用戶登錄後,其用戶信息、擁有的角色/權限不必每次去查, 這樣可以提高效率。Concurrency:shiro 支持多線程應用的並發驗證,即如在一個線程中開啟另一個線程,能把權限自動傳播過去。Testing:提供測試支持。Run As:允許一個用戶假裝為另一個用戶(如果他們允許)的身份進行訪問。Remember Me:記住我,這個是非常常見的功能,即一次登錄後,下次再來的話不用登錄了。Shiro 的運行原理

Subject:主體,可以看到主體可以是任何與應用交互的「用戶」。

SecurityManager:相當於 SpringMVC 中的 DispatcherServlet 或者 Struts2 中的 FilterDispatcher。它是 Shiro 的核心,所有具體的交互都通過

SecurityManager 進行控制。它管理著所有 Subject、且負責進行認證和授權、及會話、緩存的管理。

Authenticator:認證器,負責主體認證的,這是一個擴展點,如果用戶覺得Shiro 默認的不好,我們可以自定義實現。其需要認證策略(Authentication Strategy),即什麼情況下算用戶認證通過了。

Authrizer:授權器,或者訪問控制器。它用來決定主體是否有權限進行相應的操作,即控制著用戶能訪問應用中的哪些功能。

Realm:可以有 1 個或多個 Realm,可以認為是安全實體數據源,即用於獲取安全實體的。它可以是 JDBC 實現,也可以是 LDAP 實現,或者內存實現等。

SessionManager:如果寫過 Servlet 就應該知道 Session 的概念,Session 需要有人去管理它的生命周期,這個組件就是 SessionManager。而 Shiro 並不僅僅可以用在 Web 環境,也可以用在如普通的 JavaSE 環境。

SessionDAO:DAO 大家都用過,數據訪問對象,用於會話的 CRUD。我們可以自定義 SessionDAO 的實現,控制 session 存儲的位置。如通過 JDBC 寫到資料庫或通過jedis 寫入 redis 中。另外 SessionDAO 中可以使用 Cache 進行緩存,以提高性能。

CacheManager:緩存管理器。它來管理如用戶、角色、權限等的緩存的。因為這些數據基本上很少去改變,放到緩存中後可以提高訪問的性能。

Cryptography:密碼模塊,Shiro 提高了一些常見的加密組件用於如密碼加密/解密的。

Shiro 的基本入門

今天我們演示 Shiro 的入門,沒有整合任何框架,只是單純的演示 Shiro 運行原理,所以無需創建經典的五張表

使用 Idea 創建一個 Maven 項目

在 pom.xml 中添加如下依賴:

<!—配置 shiro 依賴-->

<dependencies>

<dependency>

<groupId>org.apache.shiro</groupId>

<artifactId>shiro-core</artifactId>

<version>1.2.3</version>

</dependency>

<dependency>

<groupId>org.slf4j</groupId>

<artifactId>slf4j-simple</artifactId>

<version>1.6.1</version>

</dependency>

</dependencies>

任意創建一個包,在裡面創建一個測試的 Demo 類:

package me.aihe;import org.slf4j.Logger; import org.slf4j.LoggerFactory;

public class Demo{

private static final transient Logger log = LoggerFactory.getLogger(Tutorial.class); public static void main(String[] args) {

log.info("My First Apache Shiro Application"); System.exit(0);

}

}創建一個 shiro.ini 配置文件

Shiro 提供了一個通用的方案通過 INI 進行配置 ,當然也可以通過 XML,YMAL,JSON 等進行配置。在 resource 目錄下面,創建一個 shiro.ini 的文件。內容如下:

# -------------------------------------------------------------------------

# Users and their (optional) assigned roles

# username = password, role1, role2, ..., roleN

# -------------------------------------------------------------------------

[users]

root = secret, admin guest = guest, guest

presidentskroob = 12345, president

darkhelmet = ludicrousspeed, darklord, schwartz aihe = aihe, goodguy, client

# -------------------------------------------------------------------------

# Roles with assigned permissions

# roleName = perm1, perm2, ..., permN

# -------------------------------------------------------------------------

[roles] admin = *

client = look:*

goodguy = winnebago:drive:eagle5

引用 Shiro.ini 配置進行測試

現在改變我們的 Demo 類文件,內容如下

import org.apache.shiro.authc.*;

import org.apache.shiro.config.IniSecurityManagerFactory;

import org.apache.shiro.mgt.SecurityManager;

import org.apache.shiro.session.Session;

import org.apache.shiro.subject.Subject;

import org.apache.shiro.util.Factory;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

public class Demo {

private static final transient Logger log = LoggerFactory.getLogger(Tutorial.class);

public static void main(String[] args) { log.info("My First Apache Shiro Application");

//1. 這裡的 SecurityManager 是 org.apache.shiro.mgt.SecurityManager,而不是

//java.lang.SecurityManager 加載配置文件

Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");

//2.解析配置文件,並且返回一些 SecurityManger 實例

SecurityManager securityManager = factory.getInstance();

//3.設置 SecurityManager 到靜態內存區,單例模式

SecurityUtils.setSecurityManager(securityManager);

// 安全操作

Subject currentUser = SecurityUtils.getSubject();

// 在應用的當前會話中設置屬性

Session session = currentUser.getSession(); session.setAttribute("key","value");

//當前我們的用戶是匿名的用戶,我們嘗試進行登錄,

if(!currentUser.isAuthenticated()){

UsernamePasswordToken token = new UsernamePasswordToken("aihe", "aihe");

token.setRememberMe(true);

//嘗試進行登錄用戶,如果登錄失敗了,我們進行一些處理

try{ currentUser.login(token);

//當我們獲登錄用戶之後

log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");

// 查看用戶是否有指定的角色

if ( currentUser.hasRole( "client" ) ) {

log.info("Look is in your role" ); } else { log.info( ". " );

}

// 查看用戶是否有某個權限

if ( currentUser.isPermitted( "look:desk" ) ) {

log.info("You can look. Use it wisely.");

} else {

log.info("Sorry, you can't look.");

}

if ( currentUser.isPermitted( "winnebago:drive:eagle5" ) ) {

log.info("You are permitted to 'drive' the 'winnebago' with license plate (id) 'eagle5'. " + "Here are

the keys - have fun!");

} else {

log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");

}

//登出currentUser.logout();

} catch ( UnknownAccountException uae ) {

//帳戶不存在的操作

} catch ( IncorrectCredentialsException ice ) {

//密碼不正確

} catch ( LockedAccountException lae ) {

//用戶被鎖定了

} catch ( AuthenticationException ae ) {

//無法判斷的情形

}

}

System.exit(0); }

}

通過 shiro 演示,我們學到了什麼

這個相對來說是一個簡單的程序,但也證明了一些 shiro 的基本用法,我們可以通過shiro 進行認證,權限控制等。

本文對 Shiro 進行了一個基本介紹,Shiro 具體在開發中的實際應用,以及更多在開發中的應用,我們並沒有具體說太多,比如和其它框架的整合等等,如果想對 Shiro 有更多的了解,請前往官網查閱。

相關焦點

  • mall改造:自定義註解和shiro權限結合,解放生產力
    這次我們聊一聊litemall中的shiro和自定義註解的組合通過上面的介紹,我們可以得知,litemall本次採用的方式,是沒有將前端與按鈕的權限一起放到資料庫中,而是將前端的頁面和權限和按鈕權限,通過註解的方式獲取。
  • 「網絡安全」關於Apache Shiro權限繞過高危漏洞的 預警通報
    近日,國家信息安全漏洞共享平臺(CNVD)公布了深信服終端檢測平臺(EDR)遠程命令執行高危漏洞,攻擊者利用該漏洞可遠程執行系統命令,獲得目標伺服器的權限。由於shiro在處理url時與spring存在差異,處理身份驗證請求時出錯導致存在身份校驗繞過漏洞,遠程攻擊者可以發送特製的HTTP請求,繞過身份驗證過程並獲得對應用程式的未授權訪問。二、影響範圍 Apache Shiro < 1.6.0。
  • Shiro權限管理框架(一):Shiro的基本使用
    <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</version></dependency>
  • Shiro入門這篇就夠了【Shiro的基礎知識、回顧URL攔截】
    )權限(權限名稱、資源id)角色(角色名稱)角色和權限關係(角色id、權限id)主體和角色關係(主體id、角色id)二、 粗粒度和細粒度權限細粒度權限管理:對資源實例的權限管理。資源實例就資源類型的具體化,比如:用戶id為001的修改連接,1110班的用戶信息、行政部的員工。細粒度權限管理就是數據級別的權限管理。粗粒度權限管理比如:超級管理員可以訪問戶添加頁面、用戶信息等全部頁面。部門管理員可以訪問用戶信息頁面包括 頁面中所有按鈕。
  • Spring Boot與Shiro整合實現用戶認證
    分析Shiro的核心APISubject: 用戶主體(把操作交給SecurityManager)SecurityManager:安全管理器(關聯Realm)Realm:Shiro連接數據的橋梁1.2.-- shiro與spring整合依賴 --><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version
  • Shiro整合redis
    在實際落地過程中,會發現如果出現集群部署服務,那麼單個服務的shiro無法認證另一個服務下面的session.
  • 30 分鐘學會如何使用 Shiro
    用戶具有角色和權限兩種最基本的屬性。例如,我的Windows登陸名稱是learnhow,它的角色是administrator,而administrator具有所有系統權限。這樣learnhow自然就擁有了所有系統權限。那麼其他人需要登錄我的電腦怎麼辦,我可以開放一個guest角色,任何無法提供正確用戶名與密碼的未知用戶都可以通過guest來登錄,而系統對於guest角色開放的權限極其有限。
  • 30分鐘學會如何使用Shiro,看這篇文章就夠了!
    用戶具有角色和權限兩種最基本的屬性。例如,我的Windows登陸名稱是learnhow,它的角色是administrator,而administrator具有所有系統權限。這樣learnhow自然就擁有了所有系統權限。那麼其他人需要登錄我的電腦怎麼辦,我可以開放一個guest角色,任何無法提供正確用戶名與密碼的未知用戶都可以通過guest來登錄,而系統對於guest角色開放的權限極其有限。
  • Apache Shiro反序化識別那些事
    1.1 關於Apache ShiroApache shiro是一個Java安全框架,提供了認證、授權、加密和會話管理功能,為解決應安全提供了相應的API:1.認證-用戶身份識別,常被稱為用戶」登錄」(理論上只要AES加密鑰洩,都會導致反序化)1.2.2 Shiro識別要想識別Apache Shiro反序列化漏,首先應該判斷相關的Web站點是否使shiro框架。
  • 披著小眾化外衣的shiro 如何做著「大眾化」生意?
    shiro就是在這塊美好的土地所誕生的品牌。公司於1989年所創立,2000年後才開始漸漸從土產轉換為護膚品。不過,品牌一開始並不叫shiro,先在2009年正式成立了品牌LAUREL之後,再在2015年決定進軍海外,才把名字改為shiro。
  • 聽歌學日語886~SUPER SHIRO
    專輯:SUPER SHIRO作曲 : 溝渕大智作詞 : 市川喜康編曲:溝渕大智君(きみ)は super shiro你就是超級小白実(じつ)は super hero其實是超級英雄わたあめフワフワ ベイベー柔軟得像棉花糖平和(へいわ)を守(ま)ってる守護和平的使者君(きみ)は super shiro你就是超級小白おなか空(あ)いても就算肚子空空世界(
  • 高版本AES-GCM模式加密的Shiro漏洞利用
    Shiro 高版本加密方式下的漏洞利用加密方式的變化Shiro高版本加密方式從AES-CBC換成了AES-GCM,由於加密算法的變化導致用於攻擊shiro
  • insp4j 輕量級權限框架 1.2.0 發布 - OSCHINA - 中文開源技術交流...
    基於Spring-EL、AOP,更加靈活易用的權限控制框架,支持權限分組,可用於一套系統多種權限隔離校驗,使用簡單、易於擴展,支持Servlet、Reactive。 參考了SpringSecurity、Expression的設計,定製擴展靈活。
  • Spring Boot+Maven+JPA+Shiro+Easyui實現通用用戶權限管理系統
    項目描述日常工作中,權限管理是管理系統必不可少的功能。網絡上有各種各樣的權限管理系統,不過用別人的總不如自己寫一套來得踏實。之前本菜鳥分享的例子裡有各種技術點的分項實例,這次做一個綜合,形成自己的簡單通用的權限管理系統。
  • 後臺權限管理設計思路:三種模型分析
    編輯導語:任何系統/產品搭建時,最先考慮的都應該是權限管理模塊,而且權限管理模塊的清晰、穩定是平臺產品健康發展的基石,權限管理核心考慮的問題是用戶與權限的關係。本文作者對三種不同權限管理的版本展開了梳理分析,與大家分享。
  • 項目實戰第2天:表單校驗
    先做一個簡單的業務分析:註冊是用戶在填寫自己的相關信息,所以其本質上是在資料庫中添加數據。瀏覽器提交請求訪問伺服器,伺服器去資料庫查詢數據判斷用戶註冊是否成功:成功:發送郵件並跳轉對應頁面,同時將用戶提交的數據添加到資料庫中。失敗:比如說用戶名已經存在,需要提示用戶註冊失敗的原因。
  • 實戰,通過複寫shiro的SessionDAO來實現將session保存到redis集群中
    關於這方面的內容可以參考我之前寫的這篇文章:https://www.zifangsky.cn/862.html但是,如果在項目中使用到了shiro框架,並且不想使用Spring Session的話,那麼我們可以通過複寫shiro的SessionDAO同樣達到將shiro管理的session保存到redis集群的目的,以此解決分布式系統架構中的session共享問題下面,我將詳細說明具體該如何來實現
  • 山西空管分局進近管制室全力保障校驗飛行
    民航資源網2020年12月7日消息:2020年12月4日,一架飛行校驗中心的獎狀C680飛機抵達太原武宿國際機場。該機預計在12月5日至12月10日之間對太原機場ILS、NDB、燈光執行校驗任務,此次校驗飛行計劃校驗科目多,時間緊任務重,空域受限和管制調配難度較大是此次校飛工作的難點。山西空管分局進近管制室高度重視這次專項保障工作。校驗機組一落地,在機場集團牽頭下,空管、校驗機組及其他相關保障部門進行了校驗飛行協調會。
  • B端產品設計:用戶角色權限系統設置
    本文首先對B端產品的用戶與需求進行了解析,進而利用RBAC模型做了權限劃分,並做了詳細的案例分析。在做過了一些B端產品後,就會發現所以B端端產品有很多共同的部分,比如系統設置裡的用戶角色權限以及基礎信息的維護,雖然B端產品可能業務不一樣,產品服務的人群、產品價值不一樣,但是用戶體系卻是每個系統必不可少的。1.