并發(fā)登錄權(quán)限控制
配置xml文件
<bean id="kickoutSessionControlFilter" class="security.shiro.filter.KickoutSessionControlFilter">
<!-- 使用cacheManager獲取相應的cache來緩存用戶登錄的會話伴找;用于保存用戶—會話之間的關(guān)系的 -->
<property name="cacheManager" ref="緩存引向注入"/>
<!-- 用于根據(jù)會話ID,獲取會話進行踢出操作的 -->
<property name="sessionManager" ref="對話引向注入"/>
<!-- 是否踢出后來登錄的向族,默認是false搀继;即后者登錄的用戶踢出前者登錄的用戶 -->
<property name="kickoutAfter" value="false"/>
<!-- 同一個用戶最大的會話數(shù)窘面,默認1;比如2的意思是同一個用戶允許最多同時兩個人登錄 -->
<property name="maxSession" value="1"/>
<!-- 被踢出后重定向到的地址 -->
<property name="kickoutUrl" value="踢出地址"/>
</bean>
攔截器繼承AccessControlFilter類
AccessControlFilter提供了訪問控制的基礎功能叽躯;比如是否允許訪問/當訪問拒絕時如何處理等:
方法onAccessDenied:表示當訪問拒絕時是否已經(jīng)處理了
- 從當前線程中獲取對象
- 如果沒有證書 或者 記住我狀態(tài)
- 跳出執(zhí)行下一段流程
- 從實體中獲取對話 取得對話和賬戶ID
- 同步控制 初始化踢出隊列 以賬戶ID為鍵值 沒有初始化則將改賬戶放入隊列中
- 檢查隊列里沒有此sessionId财边,且用戶沒有被踢出;沒有則放入隊列
- 如果隊列里的sessionId數(shù)超出最大會話數(shù)(超過)点骑,開始踢人 移除值為seesionID對應的對話
- 監(jiān)測自身對話是否被踢出酣难,如果被踢出了,直接退出黑滴,重定向到踢出后的地址 該攔截器實例已經(jīng)處理了 流程不需要繼續(xù)
- 第七項不滿足時繼續(xù)下一段流程
登錄(login)操作
org.apache.shiro.subject.Subject.login(token)憨募;
委托給SecurityManager進行登錄操作 Subject subject = securityManager.login(this, token);
根據(jù)token獲取對應的證書信息 Authenticator才是真正的身份驗證者,Shiro API中核心的身份認證入口點
重寫MyShiroRealm類繼承AuthorizingRealm
Shiro從從Realm獲取安全數(shù)據(jù)(如用戶袁辈、角色菜谣、權(quán)限)
<bean id="Realm配置ID" class="配置類路徑">
<property name="cacheManager" ref="shiroCacheManager" />
</bean>
- 獲取UsernamePasswordToken
- 查詢用戶授權(quán)信息 獲取角色名并放入role的name中
- 根據(jù)角色配置權(quán)限信息
- 返回對應賬戶
- 根據(jù)賬戶ID重新從數(shù)據(jù)庫中獲取一次賬戶(Shiro的)
- 返回授權(quán)和角色都沒有緩存的用戶(包括ID,密碼,名字)
- 可以通過設置subject session對話中超時時間尾膊,默認為30分鐘媳危,-1為永不超時