日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Apache Shiro第1部分–基础

發布時間:2023/12/3 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Apache Shiro第1部分–基础 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Apache Shiro (最初稱為JSecurity)是Java安全框架。 它被接受并于2010年成為Apache頂級項目。它的目標是功能強大且易于使用。

該項目正在積極開發中,用戶和開發人員的郵件列表均處于活動狀態。 最重要的區域記錄在其網頁上。 但是,它在文檔上有很多空白。 僅從文檔中就不可能學會使用大多數Shiro功能。 幸運的是,該代碼的注釋很好,在我嘗試過的地方也很容易閱讀。

Shiro的主要功能是:

  • 驗證,
  • 授權,
  • 密碼學
  • 會話管理。

在本文中,我們嘗試演示Shiro的各種功能。 我們從簡單的不安全Web應用程序開始,然后向其中添加安全功能。 所有代碼均在Github上的SimpleShiroSecuredApplication項目中可用。
不安全的應用程序

不安全的應用程序代碼位于unsecured_application分支中。 應用程序代表一個虛構公司的內部系統。 該公司有四個部門:

  • 管理員,
  • 修理工
  • 科學家們,
  • 銷售。

每個部門都有自己的頁面。 每個頁面都包含用戶用來完成其工作的按鈕。 當用戶按下按鈕時,工作就完成了。 例如,任何維修人員都可以轉到維修人員頁面,然后按“維修冰箱”按鈕。 該按鈕將修復冰箱并顯示成功消息。

每個用戶都有自己的帳戶頁面。 帳戶頁面包含用戶的私人數據。 由于不安全的應用程序尚無用戶,因此帳戶頁面不執行任何操作。 此外,還有一個頁面包含所有應用程序功能。 任何人都可以做的所有事情都可以在此頁面上完成。

任何人都可以做任何工作并查看所有頁面 。示例應用程序在測試類RunWaitTest中運行。 以這種方式使用單元測試不是最佳實踐,但現在并不重要。 如果您運行該類,則該應用程序將位于http:// localhost:9180 / simpleshirosecuredapplication / url中。

添加身份驗證

首先,我們必須驗證用戶的身份。 最簡單,最標準的身份驗證是通過用戶名和密碼來完成的。 用戶填寫其用戶名和密碼,然后系統驗證提供的值是否與某個用戶帳戶匹配。

對于最簡單的應用程序,將用戶名和密碼存儲在純文本文件中就足夠了。 在更現實的情況下,用戶名和密碼存儲在持久性存儲中,或者通過其他系統(例如ldap或活動目錄)進行驗證。 Shiro支持所有提到的身份驗證方法。 如果開箱即用的身份驗證功能不足,則可以使用自己的驗證實現來擴展框架。

在本章中,我們將基于用戶名和密碼的身份驗證添加到應用程序中。 用戶名和密碼存儲在靜態純文本Shiro ini文件中。

新要求:可以登錄和注銷用戶。 該應用程序僅可用于登錄用戶。 成功登錄會將用戶重定向到他自己的帳戶頁面。 所有登錄用戶仍然可以訪問所有應用程序功能和頁面。

所需步驟:

  • 添加Apache Shiro,
  • 創建登錄頁面,
  • 配置用戶和密碼,
  • 創建注銷頁面。

添加Apache Shiro

Shiro通過Servlet過濾器集成到Web應用程序中。 過濾器在servlet之前攔截請求和響應,并執行所有必要的任務(例如,標識當前登錄的用戶,將登錄的用戶附加到當前線程等)。 默認的Shiro篩選器提供基本的安全功能,例如:

  • 強制用戶登錄,
  • 執行ssl,
  • 檢查頁面訪問權限。

如果您想了解有關默認Shiro過濾器的更多信息,那么最好的起點是DefaultFilter枚舉。 它列出了所有默認可用的Shiro過濾器。 如果這些不足以滿足您的需求,則可以創建自定義的。

我們將使用高度可配置的IniShiroFilter 。 它從ini文件讀取Shiro配置并初始化安全框架。 它不執行任何安全檢查。 權限檢查,用戶登錄,協議檢查等都委托給默認或自定義過濾器。 IniShiroFilter僅初始化它們。

文檔和javadoc中都介紹了Ini配置。 Ini文件配置包含四個部分:

  • [main]部分包含Shiro初始化。 過濾器和自定義對象在此處配置。
  • [用戶]部分定義用戶,密碼和角色。
  • [角色]部分將角色與權限相關聯。
  • [urls]部分指定對應用程序頁面(url)的訪問權限。 通過將默認或自定義過濾器綁定到url來完成此操作。

將Apache Shiro依賴項添加到pom.xml:

<properties><shiro.version>1.1.0</shiro.version> </properties> <dependencies><dependency><groupid>org.apache.shiro</groupid><artifactid>shiro-core</artifactid><version>${shiro.version}</version></dependency><dependency><groupid>org.apache.shiro</groupid><artifactid>shiro-web</artifactid><version>${shiro.version}</version></dependency> </dependencies>

創建Shiro.ini文件并將其放在類路徑中。 將web.xml配置為在每個請求之前調用IniShiroFilter:

<filter><filter-name>ShiroFilter</filter-name><filter-class>org.apache.shiro.web.servlet.IniShiroFilter</filter-class><init-param><param-name>configPath</param-name><param-value>classpath:Shiro.ini</param-value></init-param> </filter><filter-mapping><filter-name>ShiroFilter</filter-name><url-pattern>/*</url-pattern> </filter-mapping>

創建登錄頁面

登錄頁面是帶有提交按鈕,用戶名和密碼字段的簡單html頁面。 登錄功能默認為Shiro authc過濾器處理。 Authc過濾器僅允許登錄用戶訪問url。 如果用戶未登錄,過濾器會將其重定向到登錄頁面。

登錄頁面上的表單名稱必須為“ loginform”,其提交方法必須為“ post”。 創建login.jsp頁面:

<form name="loginform" action="" method="post"> <table align="left" border="0" cellspacing="0" cellpadding="3"><tr><td>Username:</td><td><input type="text" name="user" maxlength="30"></td></tr><tr><td>Password:</td><td><input type="password" name="pass" maxlength="30"></td></tr><tr><td colspan="2" align="left"><input type="checkbox" name="remember"><font size="2">Remember Me</font></td></tr><tr><td colspan="2" align="right"><input type="submit" name="submit" value="Login"></td></tr> </table> </form>

為所有應用程序頁面啟用authc過濾器:

[main] # specify login page authc.loginUrl = /simpleshirosecuredapplication/account/login.jsp# name of request parameter with username; if not present filter assumes 'username' authc.usernameParam = user # name of request parameter with password; if not present filter assumes 'password' authc.passwordParam = pass # does the user wish to be remembered?; if not present filter assumes 'rememberMe' authc.rememberMeParam = remember# redirect after successful login authc.successUrl = /simpleshirosecuredapplication/account/personalaccountpage.jsp[urls] # enable authc filter for all application pages /simpleshirosecuredapplication/**=authc

更新: Shiro自動執行上下文相關的路徑匹配。 由于SimpleShiroSecuredApplication沒有設置上下文路徑,因此Shiro.ini中的完整路徑是必需的。 但是,如果應用程序上下文路徑為/ simpleshirosecuredapplication,則路徑可能是相對的:例如,簡單的/ ** = authc或/account/personalaccountpage.jsp。

由于通過網絡發送未加密的用戶名和密碼是不安全的,因此我們應強制使用ssl登錄。 SSL過濾器正是這樣做的。 它具有一個可選參數:ssl端口號。 如果省略port參數,它將使用默認的ssl端口443。

在Shiro中配置ssl之前,我們必須在Web服務器上啟用它。 具體操作取決于Web服務器。 我們展示了如何在Jetty中啟用它。 首先,使用自簽名證書創建密鑰庫:

keytool -genkey -keyalg RSA -alias jetty -keystore keystore -storepass secret -validity 360 -keysize 2048

回答所有問題,最后按Enter鍵,以便密鑰庫密碼和密鑰密碼相同。

其次,將密鑰庫添加到項目中,并將Jetty配置為使用ssl。 Java代碼在AbstractContainerTest類中可用。

現在,可以在Shiro.ini中配置ssl過濾器:

[urls] # force ssl for login page /simpleshirosecuredapplication/account/login.jsp=ssl[8443],authc # enable authc filter for the all application pages; as Shiro reads urls from up to down, must be last /simpleshirosecuredapplication/**=authc

配置用戶和密碼

現在,SimpleShiroSecuredApplication僅適用于登錄用戶。 現在,我們需要添加一些用戶,以便人們可以登錄。配置在Shiro.ini文件的[用戶]部分中完成。 部分條目的格式為:

username = password, roleName1, roleName2, ..., roleNameN

以下部分創建七個用戶,所有用戶都具有相同的密碼“ heslo”:

[users] administrator=heslo,Administrator friendlyrepairmen=heslo,repairmen unfriendlyrepairmen=heslo,repairmen mathematician=heslo,scientist physicien=heslo,scientist productsales=heslo,sales servicessales=heslo,sales

現在可以登錄到應用程序。 但是,如果用戶犯了錯誤,則不會顯示任何合理的錯誤消息。 此外,密碼存儲在純文本文件中。

錯誤處理

如果用戶在登錄時出錯,則Shiro會將其重定向回登錄頁面。 該頁面看起來與以前完全相同,這可能會使用戶感到困惑。

新要求:每次嘗試登錄失敗后,顯示錯誤消息。

每當發生身份驗證錯誤時,都會引發異常。 默認情況下,表單身份驗證過濾器會捕獲異常并將其類名稱存儲在request參數中。 由于我們希望自定義發送到頁面的數據,因此我們必須擴展FormAuthenticationFilter并重寫setFailureAttribute方法:

@Override protected void setFailureAttribute(ServletRequest request, AuthenticationException ae) {String message = ae.getMessage();request.setAttribute(getFailureKeyAttribute(), message); }

用VerboseFormAuthenticationFilter替換表單授權過濾器,并將其配置為使用'simpleShiroApplicationLoginFailure'請求屬性來保存錯誤信息:

[main] # replace form authentication filter with verbose filter authc = org.meri.simpleshirosecuredapplication.servlet.VerboseFormAuthenticationFilter # request parameter with login error information; if not present filter assumes 'shiroLoginFailure' authc.failureKeyAttribute=simpleShiroApplicationLoginFailure

在login.jsp頁面中顯示錯誤:

<% String errorDescription = (String) request.getAttribute("simpleShiroApplicationLoginFailure");if (errorDescription!=null) { %> Login attempt was unsuccessful: <%=errorDescription%> <% } %>

當心:真實的應用程序不應顯示太多的登錄錯誤信息。 消息“嘗試登錄失敗。” 沒有更多信息通常就足夠了。

散列密碼

當前應用程序版本的所有密碼均以純文本格式存儲。 最好只存儲和比較密碼哈希。

負責身份驗證的對象稱為領域 。 默認情況下,Shiro使用帶可插入密碼匹配器的IniRealm來比較密碼。 我們將用ini的SHA-256哈希替換ini中的密碼,并將IniRealm配置為使用SHA-256哈希匹配器。

生成密碼的SHA-256哈希:

import org.apache.shiro.crypto.hash.Sha256Hash;public static void main(String[] args) {Sha256Hash sha256Hash = new Sha256Hash("heslo");System.out.println(sha256Hash.toHex()); }

將Shiro配置為比較密碼哈希而不是密碼本身:

[main] # define matcher matching hashes instead of passwords sha256Matcher = org.apache.shiro.authc.credential.HashedCredentialsMatcher sha256Matcher.hashAlgorithmName=SHA-256# enable matcher in iniRealm (object responsible for authentication) iniRealm.credentialsMatcher = $sha256Matcher

用密碼哈希替換用戶密碼:

[users] administrator=56b1db8133d9eb398aabd376f07bf8ab5fc584ea0b8bd6a1770200cb613ca005, Administrator friendlyrepairmen=56b1db8133d9eb398aabd376f07bf8ab5fc584ea0b8bd6a1770200cb613ca005, repairmen unfriendlyrepairmen=56b1db8133d9eb398aabd376f07bf8ab5fc584ea0b8bd6a1770200cb613ca005, repairmen mathematician=56b1db8133d9eb398aabd376f07bf8ab5fc584ea0b8bd6a1770200cb613ca005, scientist physicien=56b1db8133d9eb398aabd376f07bf8ab5fc584ea0b8bd6a1770200cb613ca005, scientist productsales=56b1db8133d9eb398aabd376f07bf8ab5fc584ea0b8bd6a1770200cb613ca005, sales servicessales=56b1db8133d9eb398aabd376f07bf8ab5fc584ea0b8bd6a1770200cb613ca005, sales

注意:無法在ini配置中指定salt。

創建注銷頁面

具有登錄功能的任何應用程序也應具有注銷功能。 使用Shiro注銷當前用戶很容易,請使用以下命令:

//acquire currently logged user and log him out SecurityUtils.getSubject().logout();

注銷頁面如下所示:

<%@ page import="org.apache.shiro.SecurityUtils" %> <% SecurityUtils.getSubject().logout();%> You have succesfully logged out.

添加授權

我們通過向應用程序添加授權來結束第一部分。 我們從限制用戶訪問頁面開始。 任何用戶都不能看到其他部門的頁面。 由于用戶仍然能夠使用“所有應用程序功能”頁面或在瀏覽器中編輯URL來執行任何操作,因此這僅為項目提供了部分安全性。 我們將其稱為頁面級授權。

然后,我們限制了用戶自己執行操作的能力。 即使用戶打開“所有應用程序功能”頁面或在瀏覽器中編輯URL,也將只允許他執行其部門特定的功能。 我們將其稱為功能級別授權。

新要求:用戶無法查看不屬于他的部門的頁面。 用戶只能執行其部門職能。 以前的規則唯一的例外是管理員,管理員可以執行管理和修復功能。

頁面授權

頁面級授權是通過角色過濾器完成的。 過濾器的參數部分可以包含任意數量的角色。 登錄的用戶只有擁有所有提供的角色,才能訪問頁面。

像往常一樣,在Shiro.ini文件中配置角色過濾器:

[urls] # force ssl for login page /simpleshirosecuredapplication/account/login.jsp=ssl[8443],authc# only users with some roles are allowed to use role-specific pages /simpleshirosecuredapplication/repairmen/**=authc, roles[repairman] /simpleshirosecuredapplication/sales/**=authc, roles[sales] /simpleshirosecuredapplication/scientists/**=authc, roles[scientist] /simpleshirosecuredapplication/adminarea/**=authc, roles[Administrator]# enable authc filter for the all application pages; as Shiro reads urls from up to down, must be last /simpleshirosecuredapplication/**=authc

測試安全性是否有效:以任何銷售用戶身份登錄,單擊“主頁”,然后單擊“維修人員頁面”鏈接。 您會看到一個難看的錯誤。

我們完成頁面授權并將錯誤替換為重定向到錯誤頁面。 默認的Shiro過濾器具有屬性validateUrl。 如果發生未經授權的訪問,過濾器會將用戶重定向到指定的url。

[main] # redirect to an error page if user does not have access rights roles.unauthorizedUrl = /simpleshirosecuredapplication/account/accessdenied.jsp

accessdenied.jsp:

<body> Sorry, you do not have access rights to that area. </body>

功能授權

現在所有部門頁面均已安全。 但是,任何用戶仍可以在“所有應用程序功能”頁面上執行任何功能。 此外,任何登錄的用戶都可以編輯url,從而可以執行任何操作。 例如,如果您以銷售人員身份登錄并將https:// localhost:8443 / simpleshirosecuredapplication / masterservlet?action = MANAGE_REPAIRMEN放入url中,則該應用程序也將執行管理修復功能(然后將引發空指針異常,但存在安全漏洞)已經完成了)。

我們為每個功能分配唯一的權限 。 它們分為幾組:

  • 所有權限都在“功能”組中,
  • 所有管理權限都在“管理”組中,
  • 所有修復權限都在“修復”組中,
  • 所有銷售權限都在“銷售”組中,
  • 所有科學許可都在“科學”組中。

Shiro支持表示為字符串的多級權限。 級別用符號“:”分隔。 例如,“功能:管理:修理工”具有三個級別:“功能”,“管理”和“修理工”。 多級權限允許輕松進行權限分組。 例如,科學組屬于功能組,并且包含三個權限:

  • 職能:科學:研究,
  • 功能:科學:寫作文章,
  • 職能:科學:準備談話。

操作將在完成記錄的用戶權限之前對其進行驗證:

public String doIt() {String neededPermission = getNeededPermission();// acquire logged user and check permissionif (SecurityUtils.getSubject().isPermitted(neededPermission))return "Function " + getName() + " run succesfully.";throw new UnauthorizedException("Logged user does not have " + neededPermission + " permission"); }

注意:實現相同目標的另一種方法是通過注釋。

PerformFunctionAndGoBackServlet servlet捕獲授權異常并將其轉換為錯誤消息:

private String performAction(String actionName) {try {Actions action = findAction(actionName);String result = action == null ? null : action.doIt();log.debug("Performed function with result: " + result);return result;} catch (ShiroException ex) {log.debug("Function failed with " + ex.getMessage() + " message.");return "Error: " + ex.getMessage();} }

最后,我們需要在Shiro.ini文件中配置角色的權限。 Shiro支持通配符以獲得多級權限。 因此,我們不必分別指定每個部門的許可:

[roles] # members of departments should be able to perform all departmental functions sales=functions:sale:* scientist=functions:science:* repairman=functions:repair:*# administrators are able to do all management functions and repair functions Administrator=functions:manage:*,functions:repair:*

您現在可以在“所有應用程序功能”頁面上嘗試功能。 如果登錄的用戶沒有所需的權限,則會在頁面頂部顯示錯誤消息。 此外,如果您以銷售人員身份登錄并嘗試入侵https:// localhost:8443 / simpleshirosecuredapplication / masterservlet?action = MANAGE_REPAIRMEN,則會在控制臺中看到錯誤消息(而不是成功消息)。

結束

最終的應用程序可以在Github上的“ static_authentication_and_authorization”分支中找到。

在第二部分中,我們將創建自定義領域,并將用戶,密碼,角色和權限從ini文件移動到數據庫。 第三部分專門介紹Apache Shiro加密軟件包。

參考: Apache Shiro第1部分– JCG合作伙伴 Maria Jurcovicova的基礎知識,來自This is Stuff博客。


翻譯自: https://www.javacodegeeks.com/2012/05/apache-shiro-part-1-basics.html

總結

以上是生活随笔為你收集整理的Apache Shiro第1部分–基础的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。