91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎樣讓Apache Shiro保護你的應用

發布時間:2021-10-11 09:53:37 來源:億速云 閱讀:99 作者:柒染 欄目:大數據

本篇文章給大家分享的是有關怎樣讓Apache Shiro保護你的應用,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

* authentication : 認證
* authorization : 授權
* cryptography : 密碼學

一:概述

(一)What is Apache Shiro?

  • Apache Shiro 是一個強大而靈活的開源安全框架,它干凈利落地處理身份認證,授權,企業會話管理和加密。

(二)Apache Shiro Features

怎樣讓Apache Shiro保護你的應用

二:核心概念:Subject,SecurityManager,Realms

(一)Subject

  • 在考慮應用安全時,你最常問的問題可能是“當前用戶是誰?”或“當前用戶允許做 X 嗎?”。

  • 對于我們而言,考慮應用安全的最自然方式就是基于當前用戶。Shiro 的 API 用它的 Subject 概念從根本上體現了這種思考方式。

  • Subject一詞是一個安全術語,其基本意思是“當前的操作用戶”。稱之為“用戶”并不準確,因為“用戶”一詞通常跟人相關。在安全領域,術語“Subject”可以是人,也可以是第三方進程、后臺帳戶(Daemon Account)或其他類似事物。它僅僅意味著**“當前跟軟件交互的東西”**。但考慮到大多數目的和用途,你可以把它認為是 Shiro 的“用戶”概念。在代碼的任何地方,你都能輕易的獲得 Shiro Subject。

import org.apache.shiro.subject.Subject;
import org.apache.shiro.SecurityUtils;
...
Subject currentUser = SecurityUtils.getSubject();
  • 一旦獲得 Subject,你就可以立即獲得你希望用 Shiro 為當前用戶做的 90% 的事情,如登錄登出訪問會話執行授權檢查等。

(二)SecurityManager

1.Subject 的“幕后”推手是 SecurityManager

  • Subject代表了當前用戶的安全操作,SecurityManager則管理所有用戶的安全操作。它是Shiro框架的核心,充當“保護傘”,引用了多個內部嵌套安全組件,它們形成了對象圖。但是,一旦 SecurityManager 及其內部對象圖配置好,它就會退居幕后,我們只負責調用Subject API 就好

2.那么,如何設置 SecurityManager 呢?

  • 這要看應用的環境。例如,Web應用通常會在Web.xml中指定一個Shiro Servlet Filter,這會創建 SecurityManager實例。

(三)Realms

  • Realm充當了Shiro與應用安全數據間的**“橋梁”或者“連接器”。也就是說,當切實與像用戶帳戶這類安全相關數據進行交互,執行認證(登錄)和授權(訪問控制)時,Shiro會從應用配置的Realm中查找很多內容**。

  • 從這個意義上講,Realm實質上是一個安全相關的DAO它封裝了數據源的連接細節,并在需要時將相關數據提供給Shiro。當配置Shiro時,你必須至少指定一個Realm,用于認證和(或)授權。配置多個 Realm 是可以的,但是至少需要一個

三:認證(authentication)

  • 認證是核實用戶身份的過程。有時這也理解為“登錄”。它是一個典型的三步驟過程。

    1. 收集用戶的身份信息,稱為當事人(principal),以及身份的支持證明,稱為證書(Credential)。

    2. 將當事人和證書提交給系統。

    3. 如果提交的證書與系統期望的該用戶身份(當事人)匹配,該用戶就被認為是經過認證的,反之則被認為未經認證的。

  • 這個過程的常見例子是大家都熟悉的“用戶 / 密碼”組合。多數用戶在登錄軟件系統時,通常提供自己的用戶名(當事人)和支持他們的密碼(證書)。如果存儲在系統中的密碼(或密碼表示)與用戶提供的匹配,他們就被認為通過認證。

  • Shiro 以簡單直觀的方式支持同樣的流程。正如我們前面所說,Shiro 有一個以 Subject 為中心的 API - 幾乎你想要用 Shiro 在運行時完成的所有事情都能通過與當前執行的 Subject 進行交互而達成。因此,要登錄 Subject,只需要簡單地調用它的 login 方法,傳入表示被提交當事人和證書(在這種情況下,就是用戶名和密碼)的 AuthenticationToken 實例。

//1. 接受提交的當事人和證書:
AuthenticationToken token = new UsernamePasswordToken(username, password);
//2. 獲取當前 Subject:
Subject currentUser = SecurityUtils.getSubject();
//3. 登錄: 
currentUser.login(token);
  • Shiro 的 API 很容易地就反映了這個常見流程。你將會在所有的 Subject 操作中繼續看到這種簡單風格。在調用了 login 方法后,SecurityManager 會收到 AuthenticationToken,并將其發送給已配置的 Realm,執行必須的認證檢查。每個 Realm 都能在必要時對提交的 AuthenticationTokens 作出反應。

  • 如果登錄失敗了會發生什么?如果用戶提供了錯誤密碼又會發生什么?通過對 Shiro 的運行時 AuthenticationException 做出反應,你可以控制失敗

//3. 登錄:
try {
    currentUser.login(token);
} catch (IncorrectCredentialsException ice) {
    …
} catch (LockedAccountException lae) {
    …
}
…
catch (AuthenticationException ae) {…
}
  • Subject 登錄成功后,他們就被認為是已認證的,通常你會允許他們使用你的應用。但是僅僅證明了一個用戶的身份并不意味著他們可以對你的應用為所欲為。這就引出了另一個問題,“我如何控制用戶能做或不能做哪些事情?”,決定用戶允許做哪些事情的過程被稱為授權

四:授權(Authorization)

  • 授權實質上就是訪問控制 - 控制用戶能夠訪問應用中的哪些內容,比如資源、Web 頁面等等。多數用戶執行訪問控制是通過使用諸如角色和權限這類概念完成的。也就是說,通常用戶允許或不允許做的事情是根據分配給他們的角色或權限決定的。那么,通過檢查這些角色和權限,你的應用程序就可以控制哪些功能是可以暴露的。Subject API 讓你可以很容易的執行角色和權限檢查。

if ( subject.hasRole(“administrator”) ) {
    // 顯示‘Create User’按鈕 
} else {
    // 按鈕置灰?
}
  • 如你所見,你的應用程序可基于訪問控制檢查打開或關閉某些功能。

  • 權限檢查是執行授權的另一種方法。上例中的角色檢查有個很大的缺陷你無法在運行時增刪角色。角色名字在這里是硬編碼,所以,如果你修改了角色名字或配置,你的代碼就會亂套!如果你需要在運行時改變角色含義,或想要增刪角色,你必須另辟蹊徑。

  • 為此,Shiro 支持了權限(permissions)概念。權限是功能的原始表述,如‘開門’,‘創建一個博文’,‘刪除‘jsmith’用戶’等。通過讓權限反映應用的原始功能,在改變應用功能時,你只需要改變權限檢查。進而,你可以在運行時按需將權限分配給角色或用戶。

  • 我們可以重寫之前的用戶檢查,取而代之使用權限檢查。

if ( subject.isPermitted(“user:create”) ) {
    // 顯示‘Create User’按鈕 
} else {
    // 按鈕置灰?
}
  • 這樣,任何具有**“user:create”**權限的角色或用戶都可以點擊‘Create User’按鈕,并且這些角色和指派甚至可以在運行時改變,這給你提供了一個非常靈活的安全模型。

  • “user:create”字符串是一個權限字符串的例子,它遵循特定的解析慣例。Shiro 借助它的 WildcardPermission支持這種開箱即用的慣例。盡管這超出了本文的范圍,你會看到在創建安全策略時,WildcardPermission 非常靈活,甚至支持像實例級別訪問控制這樣的功能。

if ( subject.isPermitted(“user:delete:jsmith”) ) {
    // 刪除‘jsmith’用戶 
} else {
    // 不刪除‘jsmith’
}

小結

  • 操作subject,最終會轉向SecurityManager,它會咨詢Realm,做出自己的訪問控制決定

  • 必要時,允許單個realm同時響應認證和授權

五:會話管理器(Session Managerment)

  • 在安全框架領域,Apache Shiro 提供了一些獨特的東西:可在任何應用或架構層一致地使用 Session API。即,Shiro 為任何應用提供了一個會話編程范式

  • 從小型后臺獨立應用到大型集群 Web 應用。這意味著,那些希望使用會話的應用開發者,不必被迫使用 Servlet 或 EJB 容器了。或者,如果正在使用這些容器,開發者現在也可以選擇使用在任何層統一一致的會話 API,取代 Servlet 或 EJB 機制。

  • 但 Shiro 會話最重要的一個好處或許就是它們是獨立于容器的。這具有微妙但非常強大的影響。例如,讓我們考慮一下會話集群。對集群會話來講,支持容錯和故障轉移有多少種容器特定的方式?Tomcat 的方式與 Jetty 的不同,而 Jetty 又和 Websphere 不一樣,等等。但通過 Shiro 會話,你可以獲得一個容器無關的集群解決方案。Shiro 的架構允許可插拔的會話數據存儲,如企業緩存、關系數據庫、NoSQL 系統等。這意味著,只要配置會話集群一次,它就會以相同的方式工作,跟部署環境無關

  • Tomcat、Jetty、JEE 服務器或者獨立應用。不管如何部署應用,毋須重新配置應用。

  • Shiro 會話的另一好處就是,如果需要,會話數據可以跨客戶端技術進行共享。例如,Swing 桌面客戶端在需要時可以參與相同的 Web 應用會話中 - 如果最終用戶同時使用這兩種應用,這樣的功能會很有用。那你如何在任何環境中訪問 Subject 的會話呢?請看下面的示例,里面使用了 Subject 的兩個方法。

Session session = subject.getSession();
Session session = subject.getSession(boolean create);
  • 這些方法在概念上等同于 HttpServletRequest API。第一個方法會返回 Subject 的現有會話,或者如果還沒有會話,它會創建一個新的并將之返回。第二個方法接受一個布爾參數,這個參數用于判定會話不存在時是否創建新會話。一旦獲得 Shiro 的會話,你幾乎可以像使用 HttpSession 一樣使用它。Shiro 團隊覺得對于 Java 開發者,HttpSession API 用起來太舒服了,所以我們保留了它的很多感覺。當然,最大的不同在于,你可以在任何應用中使用 Shiro 會話,不僅限于 Web 應用。

Session session = subject.getSession();
session.getAttribute("key", someValue);
Date start = session.getStartTimestamp();
Date timestamp = session.getLastAccessTime();
session.setTimeout(millis);
...

六:加密(Cryptography)

  • 加密是隱藏或混淆數據以避免被偷窺的過程。在加密方面,Shiro 的目標是簡化并讓 JDK 的加密支持可用。

  • 清楚一點很重要,一般情況下,加密不是特定于 Subject 的,所以它是 Shiro API 的一部分,但并不特定于 Subject。你可以在任何地方使用 Shiro 的加密支持,甚至在不使用 Subject 的情況下。對于加密支持,Shiro 真正關注的兩個領域是加密哈希(又名消息摘要)和加密密碼

(一)哈希

  • 如果你曾使用過 JDK 的MessageDigest類,你會立刻意識到它的使用有點麻煩。MessageDigest 類有一個笨拙的基于工廠的靜態方法 API,它不是面向對象的,并且你被迫去捕獲那些永遠都不必捕獲的 Checked Exceptions。如果需要輸出十六進制編碼或 Base64 編碼的消息摘要,你只有靠自己 - 對上述兩種編碼,沒有標準的 JDK 支持它們。Shiro 用一種干凈而直觀的哈希 API 解決了上述問題。

  • 打個比方,考慮比較常見的情況,使用 MD5 哈希一個文件,并確定該哈希的十六進制值。被稱為‘校驗和’,這在提供文件下載時常用到 - 用戶可以對下載文件執行自己的 MD5 哈希。如果它們匹配,用戶完全可以認定文件在傳輸過程中沒有被篡改。

1.不使用Shiro,你需要如下步驟才能完成上述內容:

1)將文件轉換成字節數組。
  • JDK 中沒有干這事的,故而你需要創建一個輔助方法用于打開FileInputStream,使用字節緩存區,并拋出相關的 IOExceptions,等等。

2)使用MessageDigest類對字節數組進行哈希,處理相關異常。
try {
    MessageDigest md = MessageDigest.getInstance("MD5");
    md.digest(bytes);
    byte[] hashed = md.digest();
} catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
}
3)將哈希后的字節數組編碼成十六進制字符。
  • JDK 中還是沒有干這事的,你依舊需要創建另外一個輔助方法,有可能在你的實現中會使用位操作和位移動。

2.使用shiro完成

String hex = new Md5Hash(myFile).toHex();
  • 當使用 Shiro 簡化所有這些工作時,一切都非常簡單明了。完成 SHA-512 哈希和密碼的 Base64 編碼也一樣簡單。

String encodedPassword = new Sha512Hash(password, salt, count).toBase64();
  • 你可以看到 Shiro 對哈希和編碼簡化了不少,挽救了你處理在這類問題上所消耗的腦細胞。

(二)密碼

  • 加密是使用密鑰對數據進行可逆轉換的加密算法。我們使用其保證數據的安全,尤其是傳輸或存儲數據時,以及在數據容易被窺探的時候。

  • 如果你曾經用過 JDK 的 Cryptography API,特別是 javax.crypto.Cipher 類,你會知道它是一頭需要馴服的極其復雜的野獸。對于初學者,每個可能的加密配置總是由一個 javax.crypto.Cipher 實例表示。必須進行公鑰 / 私鑰加密?你得用 Cipher。需要為流操作使用塊加密器(Block Cipher)?你得用 Cipher。需要創建一個 AES 256 位 Cipher 來保護數據?你得用 Cipher。你懂的。

  • 那么如何創建你需要的 Cipher 實例?您得創建一個非直觀、標記分隔的加密選項字符串,它被稱為“轉換字符串(transformation string)”,把該字符串傳給 Cipher.getInstance 靜態工廠方法。這種字符串方式的 cipher 選項,并沒有類型安全以確保你正在用有效的選項。這也暗示沒有 JavaDoc 幫你了解相關選項。并且,如果字符串格式組織不正確,你還需要進一步處理 Checked Exception,即便你知道配置是正確的。如你所見,使用 JDK Cipher 是一項相當繁重的任務。很久以前,這些技術曾經是 Java API 的標準,但是世事變遷,我們需要一種更簡單的方法。

  • Shiro 通過引入它的 CipherService API 試圖簡化加密密碼的整個概念。CipherService 是多數開發者在保護數據時夢寐以求的東西:簡單、無狀態、線程安全的 API,能夠在一次方法調用中對整個數據進行加密或解密。你所需要做的只是提供你的密鑰,就可根據需要加密或解密。

AesCipherService cipherService = new AesCipherService();
cipherService.setKeySize(256);

// 創建一個測試密鑰: 
byte[] testKey = cipherService.generateNewKey();
// 加密文件的字節: 
byte[] encrypted = cipherService.encrypt(fileBytes, testKey);
  • 較之 JDK 的 Cipher API,Shiro 的示例要簡單的多:

    1. 你可以直接實例化一個 CipherService - 沒有奇怪或讓人混亂的工廠方法;

    2. Cipher 配置選項可以表示成 JavaBean - 兼容的 getter 和 setter 方法 - 沒有了奇怪和難以理解的“轉換字符串”;

    3. 加密和解密在單個方法調用中完成;

    4. 沒有強加的 Checked Exception。如果愿意,可以捕獲 Shiro 的 CryptoException。

  • Shiro 的 CipherService API 還有其他好處,如同時支持基于字節數組的加密 / 解密(稱為“塊”操作)和基于流的加密 / 解密(如加密音頻或視頻)。

  • 不必再忍受 Java Cryptography 帶來的痛苦。Shiro 的 Cryptography 支持就是為了減少你在確保數據安全上付出的努力。

七:web支持(Web Support)

  • Shiro 附帶了一個幫助保護 Web 應用的強建的 Web 支持模塊。對于 Web 應用,安裝 Shiro 很簡單。唯一需要做的就是在 web.xml 中定義一個 Shiro Servlet 過濾器。

(一)web.xml中的ShiroFilter

<filter>
    <filter-name>ShiroFilter</filter-name>
    <filter-class>org.apache.shiro.web.servlet.IniShiroFilter</filter-class>
    <!-- 沒有 init-param 屬性就表示從 classpath:shiro.ini 裝入 INI 配置 --> 
</filter>
<filter-mapping>
    <filter-name>ShiroFilter</filter-name>
    <url-pattern>/*</url-pattern> 
</filter-mapping>
  • 這個過濾器可以讀取shiro.ini配置,這樣不論什么開發環境,你都擁有了一致的配置。一旦完成配置,Shiro Filter就會過濾每個請求并且確保在請求期間特定請求的Subject是可訪問的。同時由于它過濾了每個請求,你可以執行安全特定的邏輯以保證只有滿足一定標準的請求才被允許通過。

(二)URL 特定的 Filter 鏈

  • Shiro 通過其創新的**URL過濾器鏈**功能支持安全特定的過濾規則。它允許你為任何匹配的 URL 模式指定非正式的過濾器鏈。這意味著, 使用 Shiro 的過濾器機制,你可以很靈活的強制安全規則(或者規則的組合) - 其程度遠遠超過你單獨在 web.xml 中定義過濾器時所獲得的。

[urls]
/assets/** = anon
/user/signup = anon
/user/** = user
/rpc/rest/** = perms[rpc:invoke], authc
/** = authc
  • Web 應用可以使用 [urls] INI 段落。對于每一行,等號左邊的值表示相對上下文的 Web 應用路徑。等號右邊的值定義了過濾器鏈 - 一個逗號分隔的有序 Servlet 過濾器列表,它會針對給出的路徑進行執行。每個過濾器都是普通的 Servlet 過濾器,你看到的上面的過濾器名字(anon,user,perms,authc)是 Shiro 內置的安全相關的特殊過濾器。你可以搭配這些安全過濾器來創建高度定制的安全體驗。你還可以指定任何其他現有的 Servlet 過濾器。

  • 相比起使用 web.xml,在其中先定義過濾器塊,然后定義單獨分離的過濾器模式塊,這種方式帶來的好處有多少?采用 Shiro 的方法,可以很容易就準確知道針對給定匹配路徑執行的過濾器鏈。如果想這么做,你可以在 web.xml 中僅定義 Shiro Filter,在 shiro.ini 中定義所有其他的過濾器和過濾器鏈,這要比 web.xml 簡潔得多,而且更容易理解過濾器鏈定義機制。即使不使用 Shiro 的任何安全特性,單憑這樣小小的方便之處,也值得讓你使用 Shiro。

(三)JSP 標簽庫

  • Shiro 還提供了 JSP 標簽庫,允許你根據當前 Subject 的狀態控制 JSP 頁面的輸出。一個有用的常見示例是在用戶登錄后顯示“Hello <username>"文本。但若是匿名用戶,你可能想要顯示其他內容,如換而顯示“Hello! Register Today!”。

<%@ taglib prefix="shiro" 
   uri="http://shiro.apache.org/tags" %>
...
<p>Hello
<shiro:user> 
    <!-- shiro:principal 打印出了 Subject 的主當事人 - 在這個示例中,就是用戶名: --> 
    <shiro:principal/>!
</shiro:user>
<shiro:guest> 
    <!-- 沒有登錄 - 就認為是 Guest。顯示注冊鏈接: --> 
    ! <a href=”register.jsp”>Register today!</a>
</shiro:guest>
</p>
  • 除了上面例子用到的標簽,還有其他標簽可以讓你根據用戶屬于(或不屬于)的角色,分配(或未分配)的權限,是否已認證,是否來自“記住我”服務的記憶,或是匿名訪客,包含輸出。

Shiro 還支持其他許多 Web 特性,如簡單的“記住我”服務,REST 和 BASIC 認證。當然,如果想使用 Shiro 原生的企業會話,它還提供透明的 HttpSession 支持。參見Apache Shiro Web 文檔可以了解更多內容。

(四)Web 會話管理

  • 最后值得一提的是 Shiro 在 Web 環境中對會話的支持。

1.缺省 Http 會話

  • 對于 Web 應用,Shiro 缺省將使用我們習以為常的 Servlet 容器會話作為其會話基礎設施。即,當你調用 subject.getSession() 和 subject.getSession(boolean) 方法時,Shiro 會返回 Servlet 容器的 HttpSession 實例支持的 Session 實例。這種方式的曼妙之處在于調用 subject.getSession() 的業務層代碼會跟一個 Shiro Session 實例交互 - 還沒有“認識”到它正跟一個基于 Web 的 HttpSession 打交道。這在維護架構層之間的清晰隔離時,是一件非常好的事情。

2.Web 層中 Shiro 的原生會話

  • 如果你由于需要 Shiro 的企業級會話特性(如容器無關的集群)而打開了 Shiro 的原生會話管理,你當然希望 HttpServletRequest.getSession() 和 HttpSession API 能和“原生”會話協作,而非 Servlet 容器會話。如果你不得不重構所有使用 HttpServletRequest 和 HttpSession API 的代碼,使用 Shiro 的 Session API 來替換,這將非常令人沮喪。Shiro 當然從來不會期望你這么做。

  • 相反,Shiro 完整實現了 Servlet 規范中的 Session 部分以在 Web 應用中支持原生會話。這意味著,不管何時你使用相應的 HttpServletRequest 或 HttpSession 方法調用,Shiro 都會將這些調用委托給內部的原生會話 API。結果,你無需修改 Web 代碼,即便是你正在使用 Shiro 的‘原生’企業會話管理 - 確實是一個非常方便(且必要)的特性。

以上就是怎樣讓Apache Shiro保護你的應用,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

富蕴县| 皮山县| 合水县| 政和县| 玉林市| 旺苍县| 诸暨市| 扬中市| 唐海县| 慈利县| 介休市| 西畴县| 内丘县| 安康市| 根河市| 大悟县| 共和县| 突泉县| 民权县| 玉树县| 平罗县| 邳州市| 赣州市| 景宁| 囊谦县| 垣曲县| 长泰县| 武功县| 微博| 仲巴县| 揭西县| 中卫市| 平江县| 安吉县| 洛浦县| 新邵县| 宝丰县| 翁源县| 双桥区| 乐至县| 西盟|