一.Shiro簡介

一.是什么?

Apache Shiro是Java的一個安全框架。Shiro可以幫助我們完成:認(rèn)證、授權(quán)、加密、會話管理、與Web集成、緩存等。
從外部看:應(yīng)用代碼直接交互的對象是Subject,也就是說Shiro的對外API核心就是Subject,Shiro不提供維護用戶/權(quán)限,而是通過Realm讓開發(fā)人員自己注入。


從內(nèi)部看:通過Securty Manage管理外部請求的認(rèn)證認(rèn)證、授權(quán)、加密、會話管理、緩存等。對應(yīng)組件是authenticator,Authorizer,session manager(自定義的sessionDao),cache manage


二.框架流程介紹

  • 容器的創(chuàng)建:通過EnvironmentLoaderListener監(jiān)聽,在容器啟動時創(chuàng)建 WebEnvironment 對象,并由該對象來讀取 Shiro 配置文件,創(chuàng)建WebSecurityManager 與FilterChainResolver 對象。
  • 執(zhí)行攔截器:因為Shiro代理了Filter,先執(zhí)行Shiro的攔截器。ShiroFilter實現(xiàn)Filter接口的init(),它是整個程序的入口。(詳細(xì)內(nèi)容見源碼分析)。執(zhí)行完Shiro攔截器后執(zhí)行其他攔截器,之后放行到WebSecurityManager進行會話的管理。
  • SecurityManager的各組件通過與subject交互進行認(rèn)證,授權(quán)等管理

三.subject介紹**

  • 定義:當(dāng)前正與軟件進行交互的任何東西,你可以把 Subject 看成是 Shiro 的"User"概念。
  • 獲?。?/strong>Subject user=SecurityUtils.getSubject()(當(dāng)前正在執(zhí)行的 Subject), 它獲取的 Subject 是基于關(guān)聯(lián)了當(dāng)前線程或傳入請求的用戶數(shù)據(jù)的。
  • 3.用途:
    • 獲取sesion :user .getSession(); (它不需要一個 HTTP 環(huán)境,任何客戶端技術(shù)現(xiàn)在能夠共享會話數(shù)據(jù))
    • .對角色和權(quán)限的檢查:
    • 是否登錄:user.isAuthenticated()
    • 是否有特定角色與操作權(quán)限:
      user.hasRole("teacher")
      user.isPermitted("teacher:save")
      user.isPermitted("teacher:save:權(quán)限碼")
    • 登錄:
    • 退出:user.logou()

四.SecurityManager組件介紹

1.Authorizer:

  • 定義:操作授權(quán)認(rèn)證組件,通過配置 Realm 實現(xiàn)或jsp標(biāo)簽,常用于角色授權(quán)

public class NormalRealm extends AuthorizingRealm{

    @Resource
    private AuthorityPermissionService permissionService;
    @Resource
    private AuthorityUsersService authorityUsersService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();//創(chuàng)建Shiro權(quán)限數(shù)據(jù)對象
        Integer userId = Integer.valueOf(principalCollection.toString());//獲取當(dāng)前用戶ID
        AuthorityUsers users = this.authorityUsersService.findById(userId);
        if (users != null) {
            if (users.getAdministrator() == 1) {
                //如果是超級管理員,賦予所有權(quán)限
                authorizationInfo.addStringPermission("*");
            } 
        }
        return authorizationInfo;
    }

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

2. Authenticator(認(rèn)證器)

  • 定義:對用戶的身份驗證(登錄)嘗試負(fù)責(zé)的組件
public class NormalRealm extends AuthorizingRealm {
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }

    //認(rèn)證
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        Object principal = usernamePasswordToken.getPrincipal();
        Object credentials = usernamePasswordToken.getCredentials();
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, credentials, getName());
        return info;
    }
}

3. SessionManager(會話管理器)

  • 定義:SessionManager是用來管理Session的組件,包括:創(chuàng)建,刪除,inactivity(失效)及驗證
  • Shiro提供了三個默認(rèn)實現(xiàn),我們常用DefaultWebSessionManager自定義管理

    * DefaultSessionManager:DefaultSecurityManager使用的默認(rèn)實現(xiàn),用于JavaSE環(huán)境;
    * ServletContainerSessionManager:用于Web環(huán)境,其直接使用Servlet容器的會話;
    * DefaultWebSessionManager:用于Web環(huán)境的實現(xiàn),可以替代2,自己維護著會話,直接廢棄了Servlet容器的會話管理。


  • 結(jié)構(gòu)圖


    image.png
  • 常用實現(xiàn)功能
    • 監(jiān)聽session狀態(tài),實現(xiàn)過程在類4中
public class sessionLister implements SessionListener {
    @Override
    public void onStart(Session session) {   
    }
    @Override
    public void onStop(Session session) {
    }
    @Override
    public void onExpiration(Session session) {
    }
}
  @Bean
    public SessionManager sessionManager(RedisSessionDAO sessionDAO) {
        sessionManager.setSessionListeners( new sessionLister() );
        return sessionManager;
    }
    • Session持久化,自定義sessionDAO組件
      sessionDAO:屬性sessionDAO,自定義SessionDAO實現(xiàn)AbstractSessionDAO,包含增刪改查方便,可以將session持久化到redis,數(shù)據(jù)庫中。但如果你不打算實現(xiàn)你自己的SessionDAO,那么強烈地建議你為Shiro 的SessionManagerment 啟用EHCache Manager 支持,將會在內(nèi)存中保存會話。
@Component
public class RedisSessionDAO extends AbstractSessionDAO {
    @Resource(name = "redisTemplate")
    private ValueOperations<Serializable, Session> valueOperations;

    @Override
    public void update(Session session) throws UnknownSessionException {
        this.saveSession(session);
    }

    @Override
    public void delete(Session session) {
        if (session == null || session.getId() == null) {
            logger.error("session or session id is null");
            return;
        }
        valueOperations.getOperations().delete(session.getId());

    }

    //用來統(tǒng)計當(dāng)前活動的session
    @Override
    public Collection<Session> getActiveSessions() {
        return sessions;
    }

    @Override
    protected Serializable doCreate(Session session) {
        return sessionId;
    }

    @Override
    protected Session doReadSession(Serializable sessionId) {
        return s;
    }
}
  @Bean
    public SessionManager sessionManager(RedisSessionDAO sessionDAO) {
        sessionManager.setSessionDAO(sessionDAO);
        return sessionManager;
    }
    • 創(chuàng)建會話Cookie的模板(參照SimpleCookie)
  @Bean
    public SessionManager sessionManager(SimpleCookie simpleCookie) {
        sessionManager.sessionIdCookie(sessionDAO);
        return sessionManager;
    }

4.緩存管理器

  • CacheManager 實例會自動地直接傳送到SessionDAO。然后當(dāng)SessionManager 要求EnterpriseCacheSessionDAO 去持久化一個Session 時,默認(rèn)它使用一個EHCache 支持的Cache實現(xiàn)去存儲Session 數(shù)據(jù),若配置其他緩存實現(xiàn),不需配置,主要是緩存到本地。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言: 近期在進行shiro權(quán)限管理進行學(xué)習(xí),網(wǎng)上找了些資料,看了開濤哥的系列學(xué)習(xí),但是感覺過于“高冷”,所以記錄...
    WDM96閱讀 660評論 0 1
  • 1.簡介 Apache Shiro是Java的一個安全框架。功能強大,使用簡單的Java安全框架,它為開發(fā)人員提供...
    H_Man閱讀 3,251評論 4 47
  • 構(gòu)建一個互聯(lián)網(wǎng)應(yīng)用,權(quán)限校驗管理是很重要的安全措施,這其中主要包含: 認(rèn)證 - 用戶身份識別,即登錄 授權(quán) - 訪...
    zhuke閱讀 3,629評論 0 30
  • Apache Shiro Apache Shiro 是一個強大而靈活的開源安全框架,它干凈利落地處理身份認(rèn)證,授權(quán)...
    羅志贇閱讀 3,332評論 1 49
  • 作者:婁山觀 更新時間:2016-12-01 01:01
    TonY_WZT閱讀 189評論 0 0

友情鏈接更多精彩內(nèi)容