javascript
Spring Shiro 入门必看
?
Shiro簡介:Shiro是一個強大的簡單易用的Java安全框架,主要用來更便捷的認證,授權,加密,會話管理。Shiro首要的和最重要的目標就是容易使用并且容易理解,通過Shiro易于理解的API,您可以快速、輕松地獲得任何應用程序——從最小的移動應用程序最大的網絡和企業應用程序。
Shiro架構圖
?
?
-
Authentication:身份認證/登錄
-
Authorization:驗證權限,即,驗證某個人是否有做某件事的權限。
-
Session Management:會話管理。管理用戶特定的會話,支持web,非web,ejb。
-
Cryptography:?加密,保證數據安全。
-
其他特性。
-
Web Support:web支持,更容易繼承web應用。
-
Caching:緩存
-
Concurrency :多線程應用的并發驗證,即如在一個線程中開啟另一個線程,能把權限自動傳播過去;
-
Testing:提供測試支持。
-
Run As:允許一個用戶假裝為另一個用戶(如果他們允許)的身份進行訪問;
-
Remember Me:記住我,即記住登錄狀態,一次登錄后,下次再來的話不用登錄了?
Shiro的架構有三個主要概念:Subject,?SecurityManager?和?Realms。下圖是一個高級的概述這些組件如何交互,下面我們將討論每一個概念:
Subject: 當前參與應用安全部分的主角。可以是用戶,可以試第三方服務,可以是cron 任務,或者任何東西。主要指一個正在與當前軟件交互的東西。所有Subject都需要SecurityManager,當你與Subject進行交互,這些交互行為實際上被轉換為與SecurityManager的交互。
SecurityManager:安全管理員,Shiro架構的核心,它就像Shiro內部所有原件的保護傘。然而一旦配置了SecurityManager,SecurityManager就用到的比較少,開發者大部分時間都花在Subject上面。當你與Subject進行交互的時候,實際上是SecurityManager在背后幫你舉起Subject來做一些安全操作。
Realms:?Realms作為Shiro和你的應用的連接橋,當需要與安全數據交互的時候,像用戶賬戶,或者訪問控制,Shiro就從一個或多個Realms中查找。Shiro提供了一些可以直接使用的Realms,如果默認的Realms不能滿足你的需求,你也可以定制自己的Realms。
Shiro詳細架構圖
The following diagram shows Shiro’s core architectural concepts followed by short summaries of each:
Subject
與應用交互的主體,例如用戶,第三方應用等。 SecurityManager SecurityManager是shiro的核心,負責整合所有的組件,使他們能夠方便快捷完成某項功能。例如:身份驗證,權限驗證等。 Authenticator 認證器,負責主體認證的,這是一個擴展點,如果用戶覺得Shiro默認的不好,可以自定義實現;其需要認證策略(Authentication Strategy),即什么情況下算用戶認證通過了。 Authorizer 來決定主體是否有權限進行相應的操作;即控制著用戶能訪問應用中的哪些功能。 SessionManager 會話管理。 SessionDAO 數據訪問對象,對session進行CRUD。 CacheManager 緩存管理器。創建和管理緩存,為 authentication, authorization 和 session management 提供緩存數據,避免直接訪問數據庫,提高效率。 Cryptography 密碼模塊,提供加密組件。 Realms 可以有1個或多個Realm,可以認為是安全實體數據源,即用于獲取安全實體的;可以是JDBC實現,也可以是LDAP實現,或者內存實現等等;由用戶提 供;注意:Shiro不知道你的用戶/權限存儲在哪及以何種格式存儲;所以我們一般在應用中都需要實現自己的Realm。第一個Apache Shiro應用
1.在pom.xml文件中添加Apache Shiro的依賴
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.1.0</version> </dependency> <!-- Shiro uses SLF4J for logging. --> <dependency><groupId>org.slf4j</groupId><artifactId>slf4j-simple</artifactId><version>1.6.1</version><scope>test</scope> </dependency>2.Shiro提供了一個通用的方案通過 INI 進行配置 ,當然也可以通過XML,YMAL,JSON等進行配置。
在resource目錄下面,創建一個shiro.ini的文件。內容如下:
src/main/resources/shiro.ini
# ============================================================================= # Tutorial INI configuration # # Usernames/passwords are based on the classic Mel Brooks' film "Spaceballs" :) # =============================================================================# ----------------------------------------------------------------------------- # Users and their (optional) assigned roles # username = password, role1, role2, ..., roleN # ----------------------------------------------------------------------------- [users] root = secret, admin guest = guest, guest presidentskroob = 12345, president darkhelmet = ludicrousspeed, darklord, schwartz lonestarr = vespa, goodguy, schwartz# ----------------------------------------------------------------------------- # Roles with assigned permissions # roleName = perm1, perm2, ..., permN # ----------------------------------------------------------------------------- [roles] admin = * schwartz = lightsaber:* goodguy = winnebago:drive:eagle5
引用Shiro.ini配置進行測試
現在改變我們的Tutorial類文件,內容如下
Final src/main/java/Tutorial.java
import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.*; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.session.Session; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.Factory; import org.slf4j.Logger; import org.slf4j.LoggerFactory;public class Tutorial {private static final transient Logger log = LoggerFactory.getLogger(Tutorial.class);public static void main(String[] args) {log.info("My First Apache Shiro Application");Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");SecurityManager securityManager = factory.getInstance();SecurityUtils.setSecurityManager(securityManager);// get the currently executing user:Subject currentUser = SecurityUtils.getSubject();// Do some stuff with a Session (no need for a web or EJB container!!!)Session session = currentUser.getSession();session.setAttribute("someKey", "aValue");String value = (String) session.getAttribute("someKey");if (value.equals("aValue")) {log.info("Retrieved the correct value! [" + value + "]");}// let's login the current user so we can check against roles and permissions:if (!currentUser.isAuthenticated()) {UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");token.setRememberMe(true);try {currentUser.login(token);} catch (UnknownAccountException uae) {log.info("There is no user with username of " + token.getPrincipal());} catch (IncorrectCredentialsException ice) {log.info("Password for account " + token.getPrincipal() + " was incorrect!");} catch (LockedAccountException lae) {log.info("The account for username " + token.getPrincipal() + " is locked. " +"Please contact your administrator to unlock it.");}// ... catch more exceptions here (maybe custom ones specific to your application?catch (AuthenticationException ae) {//unexpected condition? error?}}//say who they are://print their identifying principal (in this case, a username):log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");//test a role:if (currentUser.hasRole("schwartz")) {log.info("May the Schwartz be with you!");} else {log.info("Hello, mere mortal.");}//test a typed permission (not instance-level)if (currentUser.isPermitted("lightsaber:weild")) {log.info("You may use a lightsaber ring. Use it wisely.");} else {log.info("Sorry, lightsaber rings are for schwartz masters only.");}//a (very powerful) Instance Level permission:if (currentUser.isPermitted("winnebago:drive:eagle5")) {log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'. " +"Here are the keys - have fun!");} else {log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");}//all done - log out!currentUser.logout();System.exit(0);} }?總結
希望這個介紹教程幫助您理解如何在一個基本的應用程序設置Shiro Shiro的主要設計概念、主體和SecurityManager。
但這是一個相當簡單的應用程序。你可能會問自己,“如果我不想使用INI用戶帳號,而想要連接到一個更復雜的用戶數據來源?”
回答這個問題需要一個小Shiro的架構的深入了解和支持配置機制。接下來我們將介紹Shiro的架構,請拭目以待吧!
翻譯自Apache Shiro 官方文檔
轉載于:https://www.cnblogs.com/oycyqr/p/9465011.html
總結
以上是生活随笔為你收集整理的Spring Shiro 入门必看的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分块简单入门
- 下一篇: JS - Class继承