一.Shiro簡(jiǎn)介

一.是什么?

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


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


二.框架流程介紹

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

三.subject介紹**

  • 定義:當(dāng)前正與軟件進(jìn)行交互的任何東西,你可以把 Subject 看成是 Shiro 的"User"概念。
  • 獲取:Subject user=SecurityUtils.getSubject()(當(dāng)前正在執(zhí)行的 Subject), 它獲取的 Subject 是基于關(guān)聯(lián)了當(dāng)前線程或傳入請(qǐng)求的用戶數(shù)據(jù)的。
  • 3.用途:
    • 獲取sesion :user .getSession(); (它不需要一個(gè) HTTP 環(huán)境,任何客戶端技術(shù)現(xiàn)在能夠共享會(huì)話數(shù)據(jù))
    • .對(duì)角色和權(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)證組件,通過(guò)配置 Realm 實(shí)現(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ù)對(duì)象
        Integer userId = Integer.valueOf(principalCollection.toString());//獲取當(dāng)前用戶ID
        AuthorityUsers users = this.authorityUsersService.findById(userId);
        if (users != null) {
            if (users.getAdministrator() == 1) {
                //如果是超級(jí)管理員,賦予所有權(quán)限
                authorizationInfo.addStringPermission("*");
            } 
        }
        return authorizationInfo;
    }

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

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

  • 定義:對(duì)用戶的身份驗(yà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(會(huì)話管理器)

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

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


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


    image.png
  • 常用實(shí)現(xiàn)功能
    • 監(jiān)聽session狀態(tài),實(shí)現(xiàn)過(guò)程在類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實(shí)現(xiàn)AbstractSessionDAO,包含增刪改查方便,可以將session持久化到redis,數(shù)據(jù)庫(kù)中。但如果你不打算實(shí)現(xiàn)你自己的SessionDAO,那么強(qiáng)烈地建議你為Shiro 的SessionManagerment 啟用EHCache Manager 支持,將會(huì)在內(nèi)存中保存會(huì)話。
@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());

    }

    //用來(lái)統(tǒng)計(jì)當(dā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)建會(huì)話Cookie的模板(參照SimpleCookie)
  @Bean
    public SessionManager sessionManager(SimpleCookie simpleCookie) {
        sessionManager.sessionIdCookie(sessionDAO);
        return sessionManager;
    }

4.緩存管理器

  • CacheManager 實(shí)例會(huì)自動(dòng)地直接傳送到SessionDAO。然后當(dāng)SessionManager 要求EnterpriseCacheSessionDAO 去持久化一個(gè)Session 時(shí),默認(rèn)它使用一個(gè)EHCache 支持的Cache實(shí)現(xiàn)去存儲(chǔ)Session 數(shù)據(jù),若配置其他緩存實(shí)現(xiàn),不需配置,主要是緩存到本地。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

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