springboot+shiro 整合與基本應用

簡介

Apache Shiro是Java的一個安全框架。目前,使用Apache Shiro的人愈來愈多,由於它至關簡單,對比Spring Security,可能沒有Spring Security作的功能強大,可是在實際工做時可能並不須要那麼複雜的東西,因此使用小而簡單的Shiro就足夠了。對於它倆到底哪一個好,這個沒必要糾結,能更簡單的解決項目問題就行了。redis

Shiro能夠很是容易的開發出足夠好的應用,其不只能夠用在JavaSE環境,也能夠用在JavaEE環境。Shiro能夠幫助咱們完成:認證、受權、加密、會話管理、與Web集成、緩存等,在此我僅僅介紹咱們公司使用的認證、受權、加密功能,對於其餘功能,小夥伴能夠發揮一下自學能力呦數據庫

在此讓咱們來了解一些shiro的一些基本的術語

  1. Authentication:

身份認證/登陸,驗證用戶是否是擁有相應的身份;編程

  1. Authorization:

受權,即權限驗證,驗證某個已認證的用戶是否擁有某個權限;即判斷用戶是否能作事情,常見的如:驗證某個用戶是否擁有某個角色。或者細粒度的驗證某個用戶對某個資源是否具備某個權限;小程序

  1. Cryptography:

加密,保護數據的安全性,如密碼加密存儲到數據庫,而不是明文存儲;微信小程序

  1. Subject:

主體,表明了當前「用戶」,這個用戶不必定是一個具體的人,與當前應用交互的任何東西都是Subject,如網絡爬蟲,機器人等;即一個抽象概念;全部Subject都綁定到SecurityManager,與Subject的全部交互都會委託給SecurityManager;能夠把Subject認爲是一個門面;SecurityManager纔是實際的執行者;緩存

  1. SecurityManager:

至關於SpringMVC中的DispatcherServlet或者Struts2中的FilterDispatcher;是Shiro的心臟;全部具體的交互都經過SecurityManager進行控制;它管理着全部Subject、且負責進行認證和受權、及會話、緩存的管理安全

  1. Realm:

域,Shiro從從Realm獲取安全數據(如用戶、角色、權限),就是說SecurityManager要驗證用戶身份,那麼它須要從Realm獲取相應的用戶進行比較以肯定用戶身份是否合法;也須要從Realm獲得用戶相應的角色/權限進行驗證用戶是否能進行操做;能夠把Realm當作DataSource,即安全數據源。微信

  1. token

    token至關於一個令牌,是將用戶的一些信息(如帳號、密碼、等)通過散列而後生成一個無心義的字符串保存在數據庫或者redis,散列不可逆,用戶登陸時只能經過從新散列而後獲得串和數據庫中的串作比較,看是否相同斷定帳號密碼是否正確網絡

shiro運行流程

  • 首先,咱們從外部來看Shiro吧,即從應用程序角度的來觀察如何使用Shiro完成工做

    1. 應用代碼經過Subject來進行認證和受權,而Subject又委託給SecurityManager;
    2. 咱們須要給Shiro的SecurityManager注入Realm,從而讓SecurityManager能獲得合法的用戶及其權限 進行判斷。
    • 對於realm的詳解

    相信看完上面的工做流程圖你們必定會產生一個疑問-->爲何要realm?請看下文分析。。。。
    shiro做爲一個安全受權框架,對於用戶安全登陸上,怎樣的用戶是安全的?怎怎樣的用戶是能夠進入的?樣的用戶該擁有什麼樣的權限?相信這些只有開發者才知道,realm正是shiro留給開發者用於自定義用戶登陸驗證和受權認證的一個類,咱們能夠經過實現Realm接口建立一個自定義的realm類,用於自定義用戶登陸驗證方式(AuthenticationInfo來完成)和受權驗證(AuthorizationInfo來完成)app

    登陸驗證

    相信你們經過上面的講解對shiro已經有了一些基本的瞭解,那麼接下來我將經過咱們公司封裝的shiro框架爲例,向你們揭祕登陸和受權功能

    1. 編寫TokenFilter來進行登陸驗證

    enter description here

    1. 在配置文件裏面配置須要進行驗證的一些mappering

    enter description here

    1. 讓咱們來看一下filter裏面主要的一個類
      enter description here
    2. 首先他調用了一個gettoken方法,返回了一個Token,讓咱們看一下gettoken方法

    enter description here
    經過查看代碼,咱們知道這個token來自於請求域,來自於用戶填寫的信息

    1. 再回到filter中咱們會發現這麼一句代碼

    boolean loginSuccess = this.login(new Token(token));
    將得到的token傳入到一個login方法中,接下來讓咱們順着這裏往下走,來到了另外一個login,裏面有這麼一句-->subject.login(token);
    enter description here

    1. 進入subject.login(token),順着一直走咱們會發現這麼一個類

    enter description here
    在這個方法裏面咱們能夠發現這麼一句-->info = authenticate(token);,咱們能夠發現這就是在間接地調用relam類裏面的咱們自動以的驗證方法

    1. 讓咱們進入relam的doGetAuthenticationInfo

    enter description here
    咱們會發現他是經過用戶數據爲key在redis中嘗試獲取有沒有對應的value,來證實是否這個用戶曾經註冊過,或者帳號密碼和一些信息是否正確

    受權

    關於受權的一些概念

    主體

    主體,即訪問應用的用戶,在Shiro中使用Subject表明該用戶。用戶只有受權後才容許訪問相應的資源。

    資源

    在應用中用戶能夠訪問的任何東西,好比訪問JSP頁面、查看/編輯某些數據、訪問某個業務方法、打印文本等等都是資源。用戶只要受權後才能訪問。

    權限

    安全策略中的原子受權單位,經過權限咱們能夠表示在應用中用戶有沒有操做某個資源的權力。即權限表示在應用中用戶能不能訪問某個資源,如:
    訪問用戶列表頁面
    查看/新增/修改/刪除用戶數據(即不少時候都是CRUD(增查改刪)式權限控制)
    打印文檔等等。。。

    如上能夠看出,權限表明了用戶有沒有操做某個資源的權利,即反映在某個資源上的操做允不容許,不反映誰去執行這個操做。因此後續還須要把權限賦予給用戶,即定義哪一個用戶容許在某個資源上作什麼操做(權限),Shiro不會去作這件事情,而是由實現人員提供。
    Shiro支持粗粒度權限(如用戶模塊的全部權限)和細粒度權限(操做某個用戶的權限,即實例級別的),後續部分介紹。

    角色

    角色表明了操做集合,能夠理解爲權限的集合,通常狀況下咱們會賦予用戶角色而不是權限,即這樣用戶能夠擁有一組權限,賦予權限時比較方便。典型的如:項目經理、技術總監、CTO、開發工程師等都是角色,不一樣的角色擁有一組不一樣的權限。

    隱式角色:

    即直接經過角色來驗證用戶有沒有操做權限,如在應用中CTO、技術總監、開發工程師可使用打印機,假設某天不容許開發工程師使用打印機,此時須要從應用中刪除相應代碼;再如在應用中CTO、技術總監能夠查看用戶、查看權限;忽然有一天不容許技術總監查看用戶、查看權限了,須要在相關代碼中把技術總監角色從判斷邏輯中刪除掉;即粒度是以角色爲單位進行訪問控制的,粒度較粗;若是進行修改可能形成多處代碼修改。

    顯示角色:

    在程序中經過權限控制誰能訪問某個資源,角色聚合一組權限集合;這樣假設哪一個角色不能訪問某個資源,只須要從角色表明的權限集合中移除便可;無須修改多處代碼;即粒度是以資源/實例爲單位的;粒度較細。、

    受權方式

    Shiro支持三種方式的受權:
    1.編程式:經過寫if/else受權代碼塊完成:
    Java代碼

    Subject subject = SecurityUtils.getSubject();  
    if(subject.hasRole(「admin」)) {  
        //有權限  
    } else {  
        //無權限  
    }

    註解式:經過在執行的Java方法上放置相應的註解完成:

    Java代碼  收藏代碼
    @RequiresRoles("admin")  
    public void hello() {  
        //有權限  
    }

    沒有權限將拋出相應的異常;

    JSP/GSP標籤:在JSP/GSP頁面經過相應的標籤完成:
    Java代碼

    <shiro:hasRole name="admin">  
    <!— 有權限 —>  
    </shiro:hasRole>

    咱們 公司如何用shiro作權限

    1. 咱們公司採用註解的方法來進行權限控制

    enter description here
    這是我從公司一個勘察項目中截下的一段代碼能夠看到-->@RequiresRoles。。。。
    它的意思就是後面的角色裏只要用戶有其中一個角色就可使用這個方法

    1. 讓咱們來看realm裏面的AuthorizationInfo方法(這個方法用於作權限的認定)

    enter description here
    咱們能夠發現它先拿到一個userid,而後經過userid爲key在redis中尋找value,而後將權限信息放入info返回,對此你們必定很好奇他在redis中拿了什麼

    1. 讓咱們來看看它在redis中拿了什麼

    enter description here
    咱們查看redis發現它拿了一個數字

    1. 這個數字就表明着他的角色,而每一個角色有每一個角色的權限

    enter description here

    以上,就是今天的所有內容。


    增鑫
    蘆葦科技Java開發工程師

    蘆葦科技-廣州專業軟件外包服務公司

    提供微信小程序、APP應用研發、UI設計等專業服務,專一於互聯網產品諮詢、品牌設計、技術研發等領域、

    訪問 www.talkmoney.cn 瞭解更多

    萬能說明書 | 早起日記Lite | 凹凸壁紙 | 言財

    相關文章
    相關標籤/搜索