【Shiro】- springmvc 整合 shiro
shiro
shiro是apache開源的安全框架,可方便用來處理使用者資訊認證、使用者授權控制、資訊加密等功能。
springmvc整合shiro步驟:
- servlet容器提供訪問的入口(web.xml):DelegatingFilterProxy
<filter> <filter-name>shiroFilter</filter-name> <filter-class> org.springframework.web.filter.DelegatingFilterProxy </filter-class> <init-param> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
工作原理:web.xml中配置DelegatingFilterProxy的Servlet物件,其代理的目標Serlvet其實是org.apache.shiro.spring.web.ShiroFilterFactoryBean,為了建立兩個DelegatingFilterProxy和ShiroFilterFactoryBean關係,主要是通過Filter名稱進行繫結的,當客戶端傳送請求時,DelegatingFilterProxy進行攔截,然後根據獲取Filter名稱,最後呼叫IOC容器的getBean的方法獲取和Filter名稱匹配的Bean,因ShiroFilterFactoryBean是FactoryBean因實際上處理客戶端請求的是shiro在IOC容器Filter的實現類
- 配置shiro的ehcache快取管理器:快取認證等資訊:(可選)
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> <!--Ehcache快取配置檔案為空則使用預設配置--> <property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml"/> </bean>
- 配置shiro的會話管理器(可選:預設ServletContainerSessionManager)
<bean id="shiroSessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="globalSessionTimeout" value="600000"/> <!-- session 有效時間為半小時 (毫秒單位)-->
<property name="sessionListeners">
<list>
<bean class="com.zhiwei.shiro.listener.sessionLisenter"/>
</list>
</property>
</bean>
- 配置shiro的realm物件:提供shiro認證/授權資料的資料域物件
<bean id="myRealm" class="com.zhiwei.shiro.realm.MyRealm" init-method="setCredentialMatcher"/>
- 配置shiro的安全管理器
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="cacheManager" ref="cacheManager"/>
<property name="sessionManager" ref="shiroSessionManager"/>
<property name="realm" ref="myRealm"/>
<!-- AuthenticationListener在認證器裡面維護 -->
<property name="authenticator.authenticationListeners">
<set>
<bean class="com.zhiwei.shiro.listener.DefineAuthenticationListener"/>
</set>
</property>
</bean>
- 配置shiro的ShiroFilterFactoryBean(真正處理客戶端請求的類)
- securityManager:安全管理器
- loginUrl:登陸頁面
- successUrl:登陸成功頁面
- unauthorizedUrl:授權失敗跳轉的頁面
- filterChainDefinitions:過濾器鏈
注意過濾器的工作順序:shiro採取第1次匹配優先,第一次匹配後後面的過濾器鏈不會匹配,順序不當可能出現"302 not found"錯誤
常用過濾器通俗解釋:(過濾路徑支援ant風格)
- logout :退出登陸過濾器:預設跳轉專案根路徑訪問地址(可自定義)
- anon:匿名過濾器:不需要認證就可以進行訪問:例如公司的首頁
- authc:認證過濾器:客戶端只有認證通過之後才能訪問(例如個人資訊)
- roles:許可權過濾器:客戶端訪問制定路徑,只有滿足指定的角色才能訪問
千萬注意:名稱必須與web.xml配置的Filter名稱一致,否則IOC找不到對應的Bean出現異常
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/toLoginPage"/>
<property name="successUrl" value="/toSuccessfulPage"/>
<property name="unauthorizedUrl" value="/toUnauthorizedPage"/>
<property name="filterChainDefinitions">
<value>
/shiroHandler/shiro-logout = logout
/shiroHandler/shiro-login = anon
/toUserPage = authc,roles[user]
/toAdminPage = authc,roles[admin]
/** = authc
</value>
</property>
</bean>
- 配置shiro元件在具備IOC Bean的生命週期活動 (傳統的Filter的生命週期是由servlet容器進行統一管理,因為DelegatingFilterProxy的緣故,實際處理客戶端請求是IOC容器裡面的Filter,因此shiro的實際處理客戶端請求的過濾器需要屬於IOC的Bean元件,因此最好將其生命週期活動交給IOC容器同一管理)
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
補充: 配置檔案AuthenticationListener/SessionListener配置
AuthenticationListener:認證監聽器:會負責監聽整個shiro認證過程的情況,對於一些專案想統計使用者登陸的請求,可以使用該介面,該介面在AuthenticatingSecurityManager的Authenticator中的authenticationListeners維護,DefaultWebSecurityManager因繼承了AuthenticatingSecurityManager:使用級聯屬性配置authenticator.authenticationListeners即可:
AuthenticationListener介面:
public interface AuthenticationListener {
void onSuccess(AuthenticationToken token, AuthenticationInfo info);
void onLogout(PrincipalCollection principals);
}
spring配置AuthenticationListener:authenticator.authenticationListeners
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="authenticator.authenticationListeners">
<set>
<bean class="com.zhiwei.shiro.listener.DefineAuthenticationListener"/>
</set>
</property>
</bean>
SessionListener:會話監聽器:顧名思義就是監聽整個會話的操作過程在SessionManager中的sessionListeners維護:
SessionListener 介面:
public interface SessionListener {
void onStart(Session session);
void onStop(Session session);
void onExpiration(Session session);
}
spring配置SessionListener :sessionListeners
<bean id="shiroSessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="sessionListeners">
<list>
<bean class="com.zhiwei.shiro.listener.sessionLisenter"/>
</list>
</property>
&l