在JAVA和J2EE中,JAAS規范是一種嘗試解決安全性的問題。 盡管JAAS用于身份驗證,但授權部分卻過于繁瑣而無法使用。 EJB和Servlet規范在方法和資源級別提供了粗粒度的授權。 但是這些太粗糙了,無法在實際應用中使用。 對于Spring用戶,Spring Security是替代方法。 但是使用起來有點復雜,尤其是授權模型。 大多數應用程序最終都會構建用于身份驗證和授權的本地解決方案。
Apache Shiro是解決此問題的開源JAVA安全框架。 它是一個優雅的框架,可讓您輕松地向應用程序添加身份驗證,授權和會話管理。
Shiro的亮點是:
它是一個純Java框架。 它可以與各種JAVA應用程序一起使用:J2SE,J2EE,Web,獨立或分布式。
它可以輕松地與各種存儲庫集成,這些存儲庫可以承載用戶和權限元數據,例如RDBM,LDAP。
它具有一個簡單直觀的權限模型,可以應用于各種問題領域。 它是一個模型,可讓您專注于問題域,而不會陷入框架中。
它內置了對會話管理的支持。
它內置了對緩存元數據的支持。
它非常容易與Spring集成。 同樣適用于任何J2EE應用程序服務器。
最重要的是,它非常易于使用。 大多數時候,集成Shiro所需要做的就是實現將Shiro與用戶和權限元數據聯系起來的REALM。
Shiro概念
SecurityManager封裝了使用Shiro的應用程序的安全配置。
主題是正在使用系統的用戶的運行時視圖。 創建主題時,不會對其進行身份驗證。 對于身份驗證,必須調用login方法,并傳遞適當的憑據。
會話表示與已驗證主題關聯的會話。 會話具有會話ID。 應用程序可以在會話中存儲任意數據。 該會話有效,直到用戶注銷或會話超時。
權限表示主題可以對應用程序中的資源執行的操作。 開箱即用Shiro支持用冒號分隔的令牌表示的權限。 每個標記都有一些邏輯含義。 例如,我的應用程序可以將權限定義為ResourceType:actions:ResourceInstance。 更具體地說,File:read:contacts.doc表示讀取文件contact.doc的權限。 該權限必須與用戶關聯,才能將該權限授予該用戶。
角色是權限的集合,這些權限可能表示執行某些組織功能的能力。 角色使用戶和權限之間的關聯更易于管理。
領域為Shiro提取用戶,權限和角色元數據。 通過實現領域并將其插入Shiro,可以使此數據可用于Shiro。 典型的領域使用關系數據庫或LDAP來存儲用戶數據。
講解
讓我們構建一個簡單的java應用程序,該應用程序執行一些身份驗證和授權。 對于本教程,您將需要:
- 阿帕克史郎
- 一個Java開發環境。 我使用Eclipse。 但是您也可以使用其他IDE或命令行工具。
- 您可以從simpleshiro.zip下載此示例的源代碼。
步驟1:創建Shiro.ini配置文件
我們將使用Shiro隨附的默認文件庫領域。 這將從shiro.ini文件中讀取用戶/權限元數據。 在隨后的教程中,我將展示如何構建一個從關系數據庫獲取數據的領域。
在Ini文件中,讓我們定義一些用戶并將一些角色與其關聯。
# Simple shiro.ini file
[users]
# user admin with password 123456 and role Administrator
admin = 123456, Administrator
# user mike with password abcdef and role Reader
mike = abcdef, Reader
# user joe with password !23abC2 and role Writer
joe = !23abC2, Writer
# -----------------------------------------------------------------------------
# Roles with assigned permissions
[roles]
# A permission is modeled as Resourcetype:actions:resourceinstances
# Administrator has permission to do all actions on all resources
Administrator = *:*:*
# Reader has permission to read all files
Reader = File:read:*
# Writer role has permission to read and write all files
Writer = File:read,write:*
在上面的shiro.ini中,我們定義了3個用戶和3個角色。 權限建模
作為冒號分隔的標記。 每個令牌可以具有多個逗號分隔的部分。 每個域和部分都授予對某個特定于應用程序的域的權限。
步驟2:將BootStrap shiro插入您的應用程序
Factory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
IniSecurityManagerFactory從shiro.ini加載配置,并為該應用程序創建單例SecurityManager。 為簡單起見,我們的shiro.ini使用默認的SecurityManager配置,該配置使用基于文本的領域,并從shiro.ini文件獲取用戶,權限和角色元數據。
步驟3:登入
Subject usr = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("mike", "abcdef");
try {usr.login(token);
}
catch (AuthenticationException ae) {log.error(ae.toString()) ;return ;
}
log.info("User [" + usr.getPrincipal() + "] logged in successfully.");
SecurityUtils是一種工廠類,用于獲取現有主題或創建新主題。 使用AuthenticationToken傳遞憑據。 在這種情況下,我們要傳遞用戶名和密碼,并因此使用UsernamePasswordToken。 然后,我們在傳入身份驗證令牌的主題上調用登錄方法。
步驟4:檢查使用者是否有權限
if (usr.isPermitted("File:write:xyz.doc")) {log.info(usr.getPrincipal() + " has permission to write xyz.doc ");
} else {log.info(usr.getPrincipal() + " does not have permission to write xyz.doc ");
}
if (usr.isPermitted("File:read:xyz.doc")) {log.info(usr.getPrincipal() + " has permission to read xyz.doc ");
} else {log.info(usr.getPrincipal() + " does not have permission to read xyz.doc ");
}
主題有一個isPermitted方法,該方法將一個權限字符串作為參數并返回true / false。
步驟5:登出
usr.logout();
注銷方法將用戶注銷。
要熟悉Shiro,請嘗試更改UsernamePasswordToken并以其他用戶身份登錄。 檢查其他權限。 修改Shiro.ini文件以創建具有不同權限的新用戶和角色。 使用不同的元數據和不同的輸入多次運行該程序。
在生產環境中,您不需要ini文件中的用戶和角色。 您希望它們位于關系數據庫或LDAP之類的安全存儲庫中。 在下一部分中,我將向您展示如何構建可以使用關系數據庫中的用戶,角色,權限元數據的Shiro領域。
參考: Apache Shiro:我們的JCG合作伙伴 Manoj在The Khangaonkar Report博客上簡化了 應用程序安全性
相關文章:
- 任何軟件開發公司應存在的服務,實踐和工具,第2部分
- 使用Spring Security保護GWT應用程序
- Java EE中的配置管理
- 2011年排名前25位的最危險軟件錯誤
- Spring MVC攔截器示例
- Java中的Google ClientLogin實用程序
翻譯自: https://www.javacodegeeks.com/2011/10/apache-shiro-application-security-made.html