Shiro總結

簡介

Shiro(希羅)的前身叫JSecurity項目,始於2003年,2008年加入Apache軟件基金會併成爲Apache頂級項目。

Shiro是一個強大而靈活的開源Java安全框架,提供了認證、授權、密碼加密、會話管理等功能。

Authentication身份認證/登錄,驗證用戶是不是擁有相應的身份;

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

Session Manager會話管理,即用戶登錄後就是一次會話,在沒有退出之前,它的所有信息都在會話中;會話可以是普通JavaSE環境的,也可以是如Web環境的;

Cryptography加密,保護數據的安全性,如密碼加密存儲到數據庫,而不是明文存儲;

Web SupportWeb支持,可以非常容易的集成到Web環境;

Caching:緩存,比如用戶登錄後,其用戶信息、擁有的角色/權限不必每次去查,這樣可以提高效率;

Concurrencyshiro支持多線程應用的併發驗證,即如在一個線程中開啓另一個線程,能把權限自動傳播過去;

Testing提供測試支持;

Run As允許一個用戶假裝爲另一個用戶(如果他們允許)的身份進行訪問;

Remember Me記住我,這個是非常常見的功能,即一次登錄後,下次再來的話不用登錄了。

記住一點,Shiro不會去維護用戶、維護權限;這些需要我們自己去設計/提供;然後通過相應的接口注入給Shiro即可。

核心概念

Subject 一個安全術語,意指“當前用戶”,這裏的用戶可以指人、第三方進程等其他事物。一旦獲得Subject,你就可以立即獲得你希望用Shiro爲當前用戶做的90%的事情,如登錄、登出、訪問會話、執行授權檢查等。這裏的關鍵點是Shiro的API非常直觀,因爲它反映了開發者以‘每個用戶’思考安全控制的自然趨勢。同時,在代碼的任何地方都能很輕鬆地訪問Subject,允許在任何需要的地方進行安全操作。所有Subject都綁定到SecurityManager,與Subject的所有交互都會委託給SecurityManager;可以把Subject認爲是一個門面;SecurityManager纔是實際的執行者。

Subject subject = SecurityUtils.getSubject();

subject.login();

SecurityManager:安全管理器;shiro框架的核心,管理所有用戶更的安全操作,引用了多個內部嵌套安全組件(如Realm、Session的管理器等);

@Bean
public SecurityManager securityManager() {
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    // 設置realm
    securityManager.setRealm(myShiroRealm());
    // 記住我
    securityManager.setRememberMeManager(rememberMeManager());
    // 自定義緩存實現 使用redis
    securityManager.setCacheManager(redisCacheManager());
    // 自定義session管理 使用redis
    securityManager.setSessionManager(sessionManager());
    return securityManager;
}

Realm域,Shiro從Realm獲取安全數據(如用戶、角色、權限),就是說SecurityManager要驗證用戶身份,那麼它需要從Realm獲取相應的用戶進行比較以確定用戶身份是否合法;也需要從Realm得到用戶相應的角色/權限進行驗證用戶是否能進行操作;可以把Realm看成DataSource,即安全數據源。Realm有兩個關鍵方法:

public class MyRealm extends AuthorizingRealm {

  @Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    // 認證
    return null;
  }

  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
      throws AuthenticationException {
    // 授權
    return null;
  }
}

Filter鏈:Shiro通過其創新的URL過濾器鏈功能支持安全特定的過濾規則,它允許你爲任何匹配的URL模式指定非正式的過濾器鏈。

使用

    常規使用:https://github.com/asdf08442a/demo2-0

    前後端分離:https://blog.csdn.net/u013615903/article/details/78781166

特點

  • 於理解的 Java Security API;
  • 簡單的身份認證(登錄),支持多種數據源(LDAP,JDBC,Kerberos,ActiveDirectory 等);
  • 對角色的簡單的籤權(訪問控制),支持細粒度的籤權;
  • 支持一級緩存,以提升應用程序的性能;
  • 內置的基於 POJO 企業會話管理,適用於 Web 以及非 Web 的環境;
  • 異構客戶端會話訪問;
  • 非常簡單的加密 API;
  • 不跟任何的框架或者容器捆綁,可以獨立運行。

源碼解讀

流程

認證過程


1、通過ini配置文件創建securityManager

2、調用subject.login方法主體提交認證,提交的token

3、securityManager進行認證,securityManager最終由ModularRealmAuthenticator進行認證。

4、ModularRealmAuthenticator調用IniRealm(給realm傳入token) 去ini配置文件中查詢用戶信息

5、IniRealm根據輸入的token(UsernamePasswordToken)從 shiro.ini查詢用戶信息,根據賬號查詢用戶信息(賬號和密碼)

         如果查詢到用戶信息,就給ModularRealmAuthenticator返回用戶信息(賬號和密碼)

         如果查詢不到,就給ModularRealmAuthenticator返回null

6、ModularRealmAuthenticator接收IniRealm返回Authentication認證信息

         如果返回的認證信息是null,ModularRealmAuthenticator拋出異常(org.apache.shiro.authc.UnknownAccountException)

         如果返回的認證信息不是null(說明inirealm找到了用戶),對IniRealm返回用戶密碼 (在ini文件中存在)
         和 token中的密碼 進行對比,如果不一致拋出異常(org.apache.shiro.authc.IncorrectCredentialsException)

授權流程

1、對subject進行授權,調用方法isPermitted("permission串")

2、SecurityManager執行授權,通過ModularRealmAuthorizer執行授權

3、ModularRealmAuthorizer執行realm(自定義的Realm)從數據庫查詢權限數據,調用realm的授權方法:doGetAuthorizationInfo

4、realm從數據庫查詢權限數據,返回ModularRealmAuthorizer

5、ModularRealmAuthorizer調用PermissionResolver進行權限串比對

6、如果比對後,isPermitted中"permission串"在realm查詢到權限數據中,說明用戶訪問permission串有權限,否則 沒有權限,拋出異常。

Filters

配置  縮寫  對應的過濾器 功能
anon AnonymousFilter 指定url可以匿名訪問
authc FormAuthenticationFilter 指定url需要form表單登錄,默認會從請求中獲取usernamepassword,rememberMe等參數並嘗試登錄,如果登錄不了就會跳轉到loginUrl配置的路徑。我們也可以用這個過濾器做默認的登錄邏輯,但是一般都是我們自己在控制器寫登錄邏輯的,自己寫的話出錯返回的信息都可以定製嘛.
authcBasic BasicHttpAuthenticationFilter 指定url需要basic登錄
logout LogoutFilter 登出過濾器,配置指定url就可以實現退出功能,非常方便
noSessionCreation NoSessionCreationFilter 禁止創建會話
perms PermissionsAuthorizationFilter 需要指定權限才能訪問
port PortFilter 需要指定端口才能訪問
rest HttpMethodPermissionFilter 將http請求方法轉化成相應的動詞來構造一個權限字符串,這個感覺意義不大,有興趣自己看源碼的註釋
roles RolesAuthorizationFilter 需要指定角色才能訪問
ssl SslFilter 需要https請求才能訪問
user UserFilter 需要已登錄或“記住我”的用戶才能訪問
     

以上是shiro的一些Filter,如我們在filterChainDefinitions裏配置了/admin=authc,roles[admin],那麼/admin這個請求會由org.apache.shiro.web.filter.authc.FormAuthenticationFilter和org.apache.shiro.web.filter.authz.RolesAuthorizationFilter這兩個filter來處理,其中authc,roles只是filter的別名。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章