志宇-shiro-web
shiro-web
- Shiro的使用場景
- Shiro的核心類
- SecurityUtils
- Subject
- DefaultWebSecurityManager
- 類圖如下
- 類圖中每個類的作用
- 主要方法
- Shiro的攔截器主要類
- DefaultFilter
- shiroFilterFactoryBean
- 一個自帶的攔截器類圖
- Shiro的Filter配置路徑說明
- Shiro配置Filter路徑
- shiro注解注解使用
- shiro緩存使用
- 類圖如下
- CachingRealm
- AuthenticatingRealm
- AuthorizingRelam
- CacheManager
- 會話管理
- 密碼加密使用
- 校驗密碼
- 加密
- 自學(xué)項目地址
Shiro的使用場景
在單機應(yīng)用集群部署環(huán)境時可以使用Shiro,因Shiro提供了相關(guān)持久化接口,底層寫好了將session持久化到redis數(shù)據(jù)庫
在微服務(wù)中不推薦使用shiro,因每個模塊都要權(quán)限校驗
Auth2.0: 用于微信端授權(quán)登錄
jwt: 用于sessionid的加密和解密技術(shù)
Shiro的核心類
SecurityUtils
用于 獲得 SecurityManager 和 Subject 對象
將這兩個對象從 ThreadLocal中獲取,或存放
Subject
這個對象主要用于一些權(quán)限校驗比如 hasRole、isAuthenticated、isRemembered、login、logout方法
Subject維護(hù)著兩個對象一個是SecurityManager,一個是Session
Subject校驗方法調(diào)用SecurityManager對象中的方法
Subject的Session對象維護(hù)著SessionManager對象
DefaultWebSecurityManager
這個類中有很多成員變量,它可以調(diào)用每個成員變量的主要方法,我們只要給這個類設(shè)置對應(yīng)的成員變量即可, 主要成員變量如下,
類圖如下
類圖中每個類的作用
DefaultSecurityManager: 用來管理 RememberMeManager、SubjectDAO、SubjectFactory、SubjectContext 對象
SessionsSecurityManager: 用來管理sessionManager對象
AuthorizingSecurityManager: 用來管理Authorizer對象
AuthenticatingSecurityManager: 用來管理Authenticator對象
RealmSecurityManager: 用來管理Realm 對象
CachingSecurityManager: 用來管理CacheManager、EventBus對象
主要方法
這個類主要使用的方法: login、logout、remember方法
login 主要流程
logout 主要流程
this.beforeLogout(subject);//調(diào)用RememberMeManager 的方法 rmm.onLogout(subject);//刷新Cookie ((LogoutAware)authc).onLogout(principals);//循環(huán)調(diào)用所有的AuthenticationListener執(zhí)行onLogout方法this.delete(subject);//subjectDAO.delete(subject); 刪除對應(yīng)的session//session.removeAttribute(DefaultSubjectContext.AUTHENTICATED_SESSION_KEY);//session.removeAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);this.stopSession(subject); ---》Session s = subject.getSession(false);//獲得 DelegatingSubject(Subject)中的Session對象DelegatingSession ---》s.stop(); --------》this.sessionManager.stop(this.key); --------------》Session session = this.lookupRequiredSession(key);--------------》session.stop(); --------------》this.onStop(session, key); --------------》this.notifyStop(session); --------------》this.afterStopped(session);Shiro的攔截器主要類
DefaultFilter
shiro總共定義了11種攔截器,我只要配置這些攔截器會攔截那些路徑即可,當(dāng)我們有特殊需求時也可以自己自定義的攔截器進(jìn)行攔截
public enum DefaultFilter {//匿名攔截器,不需要登錄即可訪問的資源,匿名用戶或游客,一般用于過濾靜態(tài)資源anon(AnonymousFilter.class),//需要認(rèn)證登錄才能訪問authc(FormAuthenticationFilter.class),//httpBasic 身份驗證攔截器authcBasic(BasicHttpAuthenticationFilter.class),//退出攔截器logout(LogoutFilter.class),noSessionCreation(NoSessionCreationFilter.class),//權(quán)限授權(quán)攔截器,驗證用戶是否擁有權(quán)限perms(PermissionsAuthorizationFilter.class),//配置哪些路徑 要固定端口才能訪問port(PortFilter.class),rest(HttpMethodPermissionFilter.class),//配置哪些路徑 要哪些角色才能訪問roles(RolesAuthorizationFilter.class),//配置哪些路徑 要https 訪問ssl(SslFilter.class),//用戶攔截器,表示必須存在用戶user(UserFilter.class);}shiroFilterFactoryBean
shiroFilterFactoryBean實現(xiàn)了Spring中的FactoryBean、BeanPostProcessor
實現(xiàn)FactoryBean接口說明,它可以給spring創(chuàng)建對象通過getObject()方法
實現(xiàn)BeanPostProcessor接口,說明它是spring的一個后置處理器
項目啟動時,后置處理器會在屬性賦值后,也就是spring每個對象初始化(spring的init方法)前后執(zhí)行
這個類的主要作用就是獲得配置的自定義Filter和默認(rèn)的Filter以及要攔截url對象創(chuàng)建放到spring中
在 getObject方法
在spring后置處理器的前置方法中
if (bean instanceof Filter) { this.applyGlobalPropertiesIfNecessary(filter); this.getFilters().put(beanName, filter); }對所有Filter 進(jìn)行攔截,包裝下,然后將Filter放到shiroFilterFactoryBean中
一個自帶的攔截器類圖
NameableFilter:
用來給這個Filter設(shè)置一個name
OncePerRequestFilter:
一個人不能在同時間執(zhí)行兩次這個方法,就好比上了一把鎖,方法執(zhí)行時候把鎖打開,執(zhí)行完打開鎖
,這里更新了sessionid的失效時間,同時執(zhí)行后面的filter
AdviceFilter
在執(zhí)行chain.doFilter(request, response);前后調(diào)用
boolean continueChain = this.preHandle(request, response);
//返回boolean類型,如果返回false則不繼續(xù)執(zhí)行
this.postHandle(request, response); 交給子類去實現(xiàn)
Shiro的Filter配置路徑說明
路徑通配符支持 ?、*、**,注意通配符匹配不 包括目錄分隔符“/” 匹配說明 ? : 匹配一個字符,如 /user? , 匹配 /user3,但不匹配/user/; * : 匹配零個或多個字符串,如 /add* ,匹配 /addtest,但不匹配 /user/1 ** : 匹配路徑中的零個或多個路徑,如 /user/** 將匹 配 /user/xxx 或 /user/xxx/yyy 例子 /user/**=filter1 /user/add=filter2Shiro配置Filter路徑
1、配置的信息要放到LinkedHashMap,否則 部分路徑無法進(jìn)行攔截,時有時無
2、要按順序放到攔截器中,權(quán)限從小到大依次放入
3、LinkedHashMap中第一個參數(shù)是 攔截路徑,第二個是攔截器名稱(名字在枚舉類DefaultFilter中)
shiro注解注解使用
不推薦使用注解,springboot中要配置一些配置類,注解才能生效
@RequiresRoles(value={"admin", "editor"}, logical= Logical.AND) 需要角色 admin 和 editor兩個角色 AND表示兩個同時成立@RequiresPermissions (value={"user:add", "user:del"}, logical= Logical.OR) 需要權(quán)限 user:add 或 user:del權(quán)限其中一個,OR是或的意思。@RequiresAuthentication 已經(jīng)授過權(quán),調(diào)用Subject.isAuthenticated()返回true@RequiresUser 身份驗證或者通過記 住我登錄的使用下面代碼替換
subject.hasRole("xxx"); subject.isPermitted("xxx"); subject. isPermittedAll("xxxxx","yyyy"); subject.checkRole("xxx"); // 無返回值,可以認(rèn)為內(nèi)部使用斷言的方式shiro緩存使用
可以將shiro的認(rèn)證和授權(quán)所得到的資源緩存起來
緩存后再次使用資源就不會走Realm中的認(rèn)證和授權(quán)方法了
類圖如下
CachingRealm
這個Realm主要起管理緩存對象,同時可以設(shè)置是否開啟緩存
因?qū)崿F(xiàn)了CacheManagerAware接口,實現(xiàn)了setCacheManager方法,要在子類中注入CacheManager對象,所以CachingRealm封裝了CacheManager 類型的對象
AuthenticatingRealm
這個Relam是在認(rèn)證時起到緩存作用, AuthenticatingRealm在構(gòu)造方法中設(shè)置了
this.authenticationCachingEnabled = false;代表默認(rèn) 認(rèn)證不會開啟緩存(因為不會頻繁登錄,用戶修改了密碼還要改緩存)
AuthorizingRelam
這個Relam是在授權(quán)時起到緩存作用, AuthorizingRelam在構(gòu)造方法中設(shè)置了
this.authorizationCachingEnabled = true;代表默認(rèn) 授權(quán)會開啟緩存 (相對來說訪問較多,修改權(quán)限次數(shù)較少)
CacheManager
//它實現(xiàn)了CacheManager 同時是抽象的 可以通過繼承他重寫緩存主要方法 //它實現(xiàn)了InitializingBean 會在spring將對象發(fā)到ioc容器中后 調(diào)用(一般用于ioc容器對象中的成員變量賦值) public abstract class AbstractCacheManager implements CacheManager, InitializingBean {)CachingRealm中有用到CacheManager類型對象,用這個對象來指定如何緩存
CacheManager是一個接口,抽象類AbstractCacheManager實現(xiàn)了 CacheManager
如果自己寫不建議使用AbstractCacheManager類作為父類,因為它會將緩存信息放到Map中
直接實現(xiàn)CacheManager接口即可,想緩存到redis中要導(dǎo)入如下依賴
會提供一個RedisCacheManager對象,它實現(xiàn)了CacheManager接口
RedisCacheManager中有一個成員變量 redisManager
redisManager用來連接redis數(shù)據(jù)庫
RedisCacheManager用來從redis中獲取數(shù)據(jù) (不能往redis中設(shè)置數(shù)據(jù),只能取)
要想往Redis中設(shè)置數(shù)據(jù)要創(chuàng)建 redisSessionDao對象
同時redisSessionDao對象要通過DefaultWebSessionManager 對象進(jìn)行綁定
會話管理
SessionManager
start 開啟一個session
getSession 通過sessionid獲得session
DefaultWebSessionManager是SessionManager 類型的
這個對象里面維護(hù)著 cacheManager 和 SessionDAO
使用redis緩存sessionid的話 就將RedisSessionDAO對象設(shè)置給SessionDAO接口
SessionDAO接口負(fù)責(zé)將sessionid緩存到指定數(shù)據(jù)庫
如何自定義sessionid key的格式和value
key要在 DefaultWebSessionManager 中進(jìn)行修改
value 要在redisSessionDAO 的SessionIdGenerator 類修改
密碼加密使用
鹽值加密
加密時候加點鹽就好了 (這個鹽可以是注冊時候 創(chuàng)建的放到用戶表中)
校驗密碼
首先要獲得輸入的密碼 和從數(shù)據(jù)庫加密的密碼
我們要將輸入的密碼加密 然后和數(shù)據(jù)庫中的密碼比對
如果我們想要自己定義方法,同時解密時候也要使用
那么shiro要在哪里進(jìn)行校驗密碼呢?
當(dāng)然是認(rèn)證環(huán)節(jié)了,也就是 AuthenticatingRealm 類了
AuthenticatingRealm中有一個對象CredentialsMatcher 這個就是用來來加密的對象
HashedCredentialsMatcher參數(shù)使用
同時 在認(rèn)證時傳入?yún)?shù)中要傳入鹽
加密
在注冊密碼和修改密碼時進(jìn)行加密
自學(xué)項目地址
總結(jié)
以上是生活随笔為你收集整理的志宇-shiro-web的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 20171110
- 下一篇: ffmpeg 处理ts视频流