cas+shiro實現不時時的去請求cas進行身分識別驗證,shirocas
cas+shiro不進行時時去cas驗證身份資訊,需要用shiro在當前系統有一份完整的認證機構。
那麼有一個問題,什麼時候去cas校正資訊,目前的配置方式:
cas系統設定預設的瀏覽器session存活時間,當前系統的session存活時間為30分鐘,那麼噹噹前系統身分識別驗證失敗是,去cas校正。
這裡涉及到一個非常重要的節點,就是shiro架構內部是怎麼進行cas校正的呢,請看代碼:
org.apache.shiro.web.filter.AccessControlFilterd還是所有預設驗證類的父類,
父類中的redirectToLogin方法就是去請求cas伺服器,重新擷取驗證資訊
/** * Convenience method for subclasses that merely acquires the {@link #getLoginUrl() getLoginUrl} and redirects * the request to that url. * <p/> * <b>N.B.</b> If you want to issue a redirect with the intention of allowing the user to then return to their * originally requested URL, don't use this method directly. Instead you should call * {@link #saveRequestAndRedirectToLogin(javax.servlet.ServletRequest, javax.servlet.ServletResponse) * saveRequestAndRedirectToLogin(request,response)}, which will save the current request state so that it can * be reconstructed and re-used after a successful login. * * @param request the incoming <code>ServletRequest</code> * @param response the outgoing <code>ServletResponse</code> * @throws IOException if an error occurs. */ protected void redirectToLogin(ServletRequest request, ServletResponse response) throws IOException { String loginUrl = getLoginUrl(); WebUtils.issueRedirect(request, response, loginUrl); }
現在要解決一個問題,就是當前系統的身分識別驗證資訊到期了,這個時候頁面向後台發起了一個ajax請求,那麼後台拿到這個請求之後直接對這個請求進行轉寄到cas服務就會出現一個問題:跨域問題。
參考解決辦法:因為我的所有後台除了首頁是用預設的org.apache.shiro.web.filter.authc.AnonymousFilter類進行身分識別驗證,其他的請求都是通過
org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter進行的許可權驗證,又因為PermissionsAuthorizationFilter繼承了AccessControlFilterd
所以我的解決辦法就是建立一個自己的PermissionsAuthorizationFilter覆蓋AccessControlFilterd的redirectToLogin方法
import java.io.IOException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter;import com.chenrd.shiro.AuthorRuntimeException;/** * 最最重要的一點,解決了頁面沒有重新整理點擊功能,但是背景author已經被登出的情況下會去發送cas請求而產生的跨域問題 * * @author chenrd * @version 2015年12月11日 * @see MyPermissionsAuthorizationFilter * @since */public class MyPermissionsAuthorizationFilter extends PermissionsAuthorizationFilter{ @Override protected void redirectToLogin(ServletRequest request, ServletResponse response) throws IOException { throw new AuthorRuntimeException("身份異常,不進行轉寄到登入頁面"); /*String loginUrl = getLoginUrl(); WebUtils.issueRedirect(request, response, loginUrl);*/ }}
然後在shiro的設定檔裡面修改如下:
<bean id="myPermissionsAuthorizationFilter" class="com.chenrd.shiro.filter.MyPermissionsAuthorizationFilter"/> <bean id="filterChainManager" class="com.chenrd.shiro.filter.CustomDefaultFilterChainManager"> <property name="loginUrl" value="${cas.url}/login?service=${apply.url}/cas"/> <property name="successUrl" value="/"/> <property name="unauthorizedUrl" value="/authority"/> <property name="customFilters"> <util:map> <entry key="cas" value-ref="casFilter"/>
<!--替換預設的許可權控制類--> <entry key="perms" value-ref="myPermissionsAuthorizationFilter"/> </util:map> </property> <property name="defaultFilterChainDefinitions"> <value> /login=anon /cas=cas /jaxws/services/**=anon /**=authc </value> </property> </bean>