shiro

<!doctype html>



shiro02


css

Shiro簡介

  • Apache的開源安全框架
  • 提供認證、受權、會話管理、安全加密、緩存管理等等相關的功能

Shiro與Spring Security對比

Shiro Spring Security
簡單,靈活 複雜,笨重
可脫離Spring 不可脫離Spring
粒度較粗 粒度更細

總體架構

主要分爲兩大塊 SubjectSecurity Managerhtml

Subject

能夠理解爲當前的操做用戶java

Security Manager

是Shiro的核心,她管理着其餘組件的實例。它包含下面這些組件node

  • Authenticator(認證)git

    咱們應用的認證器,管理登陸,登出github

  • Authorizer(受權)web

    咱們應用的受權器,主要賦予Subject(當前的操做用戶)有哪些權限算法

  • Session Managerspring

    Shiro本身實現的一套管理機制,能夠在不借用任何web容器下使用session,下面的Session Dao是提供了一些Session的操做,主要有增刪改查sql

  • Cache Manager

    緩存管理器,主要用於緩存角色數據和權限數據

  • Realms

    充當了 Shiro 與應用安全數據間的「橋樑」或者「鏈接器」,Shiro經過它來從數據庫中獲取認證數據、角色數據和權限數據。

  • Cryptography(加密)

    Shiro提供的加密工具,能夠使用她很是快捷,方便的來作數據加密

  • 更多信息查看 官方架構文檔

認證

更多信息請查看 認證官方文檔

認證過程

Created with Raphaël 2.2.0 建立SecurityManager Subject提交認證請求 SecurityManager認證 Authenticator認證 Realm認證
  1. 建立Shiro的核心SecurityManager對象,構建Shiro環境
  2. Subject提交認證請求,至關於登陸操做,實際上會提交到SecurityManager進行認證
  3. SecurityManager則會使用父類屬性authenticator進行認證
  4. Authenticator則會先獲取全部的Realm,而後會查詢Cache中是否存在認證信息沒有,則會去Realm中認證。多個Realm會循環認證,都是先查詢Cache而後查詢Realm
  5. Realm會查詢數據庫裏面的數據,它會拋出必定的異常,表明認證失敗

受權

更多信息請查看 受權官方文檔

受權過程

Created with Raphaël 2.2.0 建立SecurityManager Subject受權 SecurityManager受權 Authorizer受權 Realm獲取角色權限數據
  1. 建立Shiro的核心SecurityManager對象,構建Shiro環境
  2. 在須要驗證權限的時候,會調用Subject受權方法,最後仍是會調用SecurityManager進行受權
  3. SecurityManager受權會使用父類屬性authorizer進行受權
  4. authorizer受權會去Cache中獲取,若是沒有則會調用SecurityManager中指定的Realm進行獲取
  5. Realm就會直接從數據庫獲取角色和權限數據

Realm

更多信息請查看 Realm官方文檔

內置Realm

IniRealm

從配置文件中獲取用戶、角色和權限數據

  
  
  
  

SecurityManager中注入 org.apache.shiro.realm.text.IniRealm 類並指定配置文件路徑便可

JdbcRealm

從數據庫中獲取用戶、角色和權限數據。可是該Realm有一些默認的查詢語句,而且指定了表名和字段名,雖然能夠修改他默認的sql語句,可是不夠方便。所以仍是自定義Realm方便一些。

SecurityManager中注入 org.apache.shiro.realm.jdbc.JdbcRealm 類並建立對應的表和字段便可

自定義Realm

建立類繼承AuthorizingRealm並實現其方法,以後在SecurityManager中注入該類便可。

實現方法以下(該實現方法採用MybatisPlus爲持久層框架)

  
  
  
  

安全加密

Shiro散列配置

HashedCredentialsMatcher

這是Shiro的一個加密工具類,能夠設置加密算法和加密算法的加密次數

hashAlgorithm 該屬性指定加密的算法

hashIterations 該屬性指定加密算法的加密次數

自定義Realm中使用散列

直接在Realm中配置HashedCredentialsMatcher並設置加密算法和次數便可

Springboot中配置加密以下

  
  
  
  

加鹽

加鹽是爲了讓密碼更加難以識破,通常都是生成一個隨機數來和密碼一塊兒使用。

直接在Realm認證方法中添加一個參數便可

  
  
  
  

下面代碼爲生成隨機鹽值和經過鹽加密後的密碼

  
  
  
  

Shiro內置攔截器

認證過濾器

org.apache.shiro.web.filter.authc.AuthenticatingFilter

過濾器 說明
anon 不須要認證,直接能夠訪問
authBasic httpBasic認證
authc 須要認證才能訪問
user 須要當前存在用戶才能訪問
logout 登出

受權過濾器

org.apache.shiro.web.filter.authz.AuthorizationFilter

過濾器 說明
perms 具有相關的權限才能夠訪問
roles 具有相關的角色才能夠訪問
ssl 安全協議,也就是https
port 訪問指定的端口才能夠訪問

更多過濾器查看 過濾器官方文檔

在ShiroFilterFactoryBean中設置屬性 filterChainDefinitionMap便可,注意他是鏈式過濾的,就是說是安裝從上到下進行過濾的。下面給出一個Springboot的例子

  
  
  
  

自定義攔截器

須要認證攔截就繼承 org.apache.shiro.web.filter.authc.AuthenticatingFilter 類,重寫父類中的方法。

須要受權攔截就繼承 org.apache.shiro.web.filter.authz.AuthorizationFilter 類,重寫父類中的方法。

寫好攔截器後須要注入到ShiroFilter中便可,更多過濾器信息請直接查看源碼進行了解

會話管理

Shiro本身實現了一套Session管理體系,他能夠使咱們在不介入Web容器和Servlet下使用Session。

更多信息查看 會話管理官方文檔

SessionManager

Shiro提供的一個Session管理器

SessionDAO

提供Session的增刪改查操做

Redis實現Session共享

  1. 自定義SessionDAO,繼承 org.apache.shiro.session.mgt.eis.AbstractSessionDAO 並重寫其方法,主要包括基本增刪改查以及獲取全部活動的Session
  2. 自定義SessionManager,建立RedisSessionManager類繼承 org.apache.shiro.web.session.mgt.DefaultWebSessionManager重寫retrieveSession方法,能夠設置爲先從Request中獲取,取不到則從Redis中獲取。這樣能夠減輕Redis的壓力
  3. 將自定義SessionManager注入到SecurityManager中

緩存管理

CacheManager,主要用來緩存角色數據和權限數據,這樣就能夠不用每次受權的時候都要去數據庫查詢角色和權限信息。主要是經過CacheManager和Cache這兩個接口來管理Cache

更多緩存信息請查看 緩存官方文檔

Redis實現緩存管理

  1. 自定義RedisCache類實現 org.apache.shiro.cache.Cache<K,V>接口並實現相應的方法
  2. 自定義CacheManager類實現 org.apache.shiro.cache.CacheManager接口並實現相應的方法
  3. 將自定義RedisCache注入到自定義的CacheManager中
  4. 再將自定義CacheManager注入到SecurityManager中

自動登陸

  1. 建立 org.apache.shiro.web.servlet.SimpleCookie對象,並設置Cookie名稱和過時時間
  2. 建立 org.apache.shiro.web.mgt.CookieRememberMeManager對象,並設置Cookie爲SimpleCookie對象
  3. 將CookieRememberMeManager對象注入到SecurityManager的屬性 rememberMeManager
  4. 在認證或登陸的時候建立的 org.apache.shiro.authc.UsernamePasswordToken 對象中設置rememberMe屬性,這是一個boolean值

示例項目

碼雲

相關文章
相關標籤/搜索