1. 程式人生 > >【Shiro】- springmvc 整合 shiro

【Shiro】- springmvc 整合 shiro

浪費了“黃金五年”的Java程式設計師,還有救嗎? >>>   

shiro

shiro是apache開源的安全框架,可方便用來處理使用者資訊認證、使用者授權控制、資訊加密等功能。

springmvc整合shiro步驟:

  1. 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的實現類

  1. 配置shiro的ehcache快取管理器:快取認證等資訊:(可選)
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <!--Ehcache快取配置檔案為空則使用預設配置-->
        <property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml"/>
    </bean>
  1. 配置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>
  1. 配置shiro的realm物件:提供shiro認證/授權資料的資料域物件
<bean id="myRealm" class="com.zhiwei.shiro.realm.MyRealm"  init-method="setCredentialMatcher"/>
  1. 配置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>
  1. 配置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>
  1. 配置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