身為一個剛剛進入開發行業的學生,進入公司就開始了Shiro框架的應用,特此在這里寫下收獲。
Shiro是apache旗下一個開源安全框架,它將軟件系統的安全認證相關的功能抽取出來,實現用戶身份認證,權限授權、加密、會話管理等功能,組成了一個通用的安全認證框架,使用shiro就可以非常快速的完成認證、授權等功能的開發,降低系統成本。
在概念層,Shiro 架構包含三個主要的理念:Subject,SecurityManager和 Realm。
詳細架構就不細說了,只從概要架構進行理解。
通過Shiro框架進行權限管理時,要涉及到的一些核心對象,主要包括:
認證管理對象,授權管理對象,會話管理對象,緩存管理對象,加密管理對象
以及Realm管理對象(領域對象:負責處理認證和授權領域的數據訪問題)
1) Subject(主體):與軟件交互的一個特定的實體(用戶、第三方服務等)。
2) SecurityManager(安全管理器) :Shiro 的核心,用來協調管理組件工作。
3) Authenticator(認證管理器):負責執行認證操作
4) Authorizer(授權管理器):負責授權檢測
5) SessionManager(會話管理):負責創建並管理用戶 Session 生命周期,提供一個強有力的 Session 體驗。
6) SessionDAO:代表 SessionManager 執行 Session 持久(CRUD)動作,它允許任何存儲的數據掛接到 session 管理基礎上。
7) CacheManager(緩存管理器):提供創建緩存實例和管理緩存生命周期的功能
8) Cryptography(加密管理器):提供了加密方式的設計及管理。
9)Realms(領域對象):是shiro和你的應用程序安全數據之間的橋梁。
以下廢話不多說,直接進入應用環節
因為我是maven所有選擇了添加了依賴
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
創建spring-shiro.xml(tomcat啟動時需要加載)
<?xml version="1.0" encoding="UTF-8"?>
<beans default-lazy-init="true"
xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.3.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd" >
<!-- 配置SecurityManager對象(Shiro框架核心,負責調用相關組件實現
用戶身份認證,授權,緩存,會話管理等功能)-->
<bean id="securityManager"
class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="Realm" ref="ShiroUserRealm"/>
</bean>
<!-- 配置ShiroFilterFactoryBean對象(Shiro中會通過很多過濾器對WEB請求
做預處理,這些過濾器的創建底層設計了一個工廠類) -->
<bean id="shiroFilterFactory" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- 注入SecurityManager對象 -->
<property name="SecurityManager" ref="securityManager"/>
<!-- 配置登錄頁面 -->
<property name="LoginUrl" value="/login.jsp"/>
<!-- 定義過濾規則(哪些資源允許匿名訪問,哪些資源必須授權訪問)-->
<property name="FilterChainDefinitionMap">
<map>
<!-- 說明:anon表示允許匿名訪問, authc表示授權訪問-->
<entry key="/css/**" value="anon"/>
<entry key="/db_sql/**" value="anon"/>
<entry key="/images/**" value="anon"/>
<entry key="/js/**" value="anon"/>
<entry key="/META-INF/**" value="anon"/>
<entry key="/yzm/**" value="anon"/>
<!-- 這里是授權的應用,以xml方式來管理,當然也有使用注解或jsp標簽的方式,在授權時我們會講解-->
<!-- <entry key="/company/deleteCompany.do" value="perms[company:delete]" /> -->
<!-- <entry key="/page/xtgl/userList.jsp" value="perms[xtgl:userList]"> -->
<entry key="/login/getLogins.do" value="anon"/>
<entry key="/doLogout.do" value="logout"/>
<entry key="/**" value="authc"/>
</map>
</property>
</bean>
<!-- 配置bean對象的生命周期管理 -->
<bean id="lifecycleBeanPostProcessor"
class="org.apache.shiro.spring.LifecycleBeanPostProcessor">
</bean>
<!-- 配置Bean對象的代理 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor">
</bean>
<!-- 配置授權Bean對象 -->
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="SecurityManager" ref="securityManager"/>
<!--自定義realm對象-->
</bean>
<bean id="ShiroUserRealm" class="com.cn.ericsson.service.realm.ShiroUserRealm">
</bean>
</beans>
在web.xml進行的操作
<!-- 配置shiro過濾器(對請求進行攔截) -->
<filter>
<filter-name>shiroFilter</filter-name>
<!-- 此類型由誰提供(spring 框架):spring整合shiro的入口 -->
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<!-- 這個參數名在DelegatingFilterProxy中定義 -->
<param-name>targetBeanName</param-name>
<!-- 這個值在spring-shiro.xml配置文件中定義 -->
<param-value>shiroFilterFactory</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
自定義realm
@Service
public class ShiroUserRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken arg0) throws AuthenticationException {
// TODO Auto-generated method stub
return null;
}
}
到此環境已經搭建完成,后期說明認證及授權
對shiro框架的補充,看補充最多先看2,3
Shiro是什么?
Shiro是apache旗下一個開源安全框架,它將軟件系統的安全認證相關的功能抽取出來
解決了什么問題
實現用戶身份認證,權限授權、加密、會話管理等功能,組成了一個通用的安全認證框架,使用shiro就可以非常快速的完成認證、授權等功能的開發,降低系統成本。
Shiro的核心對象
1) Subject:與軟件交互的一個特定的實體(用戶、第三方服務等)。
2) SecurityManager :Shiro 的核心,用來協調管理組件工作。
3) Authenticator:負責執行認證操作(認證管理器)
4) Authorizer:負責授權檢測(授權管理器)
5) SessionManager:負責創建並管理用戶 Session 生命周期,提供一個強有力的 Session 體驗。(回話管理器)
6) SessionDAO:代表 SessionManager 執行 Session 持久(CRUD)動作,它允許任何存儲的數據掛接到 session 管理基礎上。
7) CacheManager:提供創建緩存實例和管理緩存生命周期的功能(緩存管理器)
8) Cryptography:提供了加密方式的設計及管理。(加密器)
9) Realms:是shiro和你的應用程序安全數據之間的橋梁。
Shiro認證流程
- 當用戶在登錄的時候,獲取登錄用戶的用戶名和密碼並將其封裝在UsernamePasswordToken對象(令牌token)中
- 然后通過主身份Subject對象調用login(token)方法將令牌傳遞給SecurityManager安全管理器.
- 安全管理器則將認證操作委托給認證管理器Authenticator.
- 認證管理器Authenticator則底層則基於認證策略將登錄用戶的身份信息傳遞給相應的Realm.
- Realm則通過登錄用戶的身份信息從數據庫獲取用戶數據,並將用戶數據封裝到SimpleAuthenticationInfo類中,返回給認證管理器.
- 認證管理器則通過比較登錄用戶的信息和從數據庫查詢出來的用戶數據來判斷當前用戶是否存在,若存在則登錄,若不存在,則拒絕登錄.
- 由於在添加用戶的時候,對用戶的密碼做了相應的MD5加密算法,所以在通過認證管理器比較用戶信息是否合法時,需要告訴認證管理器用戶的密碼是通過MD5加密算法加密過得,若不告訴則密碼將永遠不會匹配.
Shiro的授權流程
當用戶登錄后執行某些操作時,需要判斷當前用戶是否有執行此操作的權限.在自定義的Realm類的授權方法中:
1) 通過PrincipalCollection對象獲取當前用戶的主身份
2) 通過這個主身份從數據庫查詢出當前用戶擁有的角色id,通過角色id去數據庫中查詢出相對應的權限id,再通過權限id從數據庫中獲取相應的權限標識.
3) 由於在某些方法上添加過Shiro自帶的@RequiredsPermissions注解,注解中寫有權限標識,如@RequiredsPermissions(“------”).所以底層將通過反射獲取到當前執行方法上的注解中的權限標識.
4) 當某方法上有@RequiredsPermissions(“-----”)注解時.就是在告訴系統執行此方法需要授權操作.底層會通過Subject對象調用isPermitted()方法判斷該用戶是否包含該注解中含有的權限標識,若有該標識則允許用戶執行該操作,若沒有該標識則表示用戶沒有執行該操作的權限.
5) 當獲取到用戶的權所有限標識之后,將權限標識(String類型的)封裝到SimpleAuthorizationInfo對象中,返回給授權管理器Authrizor,底層判斷用戶是否具執行該操作的權限.