1. 程式人生 > >CAS-Client客戶端研究(一)-AuthenticationFilter

CAS-Client客戶端研究(一)-AuthenticationFilter

最近研究CAS,先從客戶開始來說明CAS的邏輯,可能會結合原始碼。

必要引數

service or serverName:

serverName:CAS客戶端的伺服器名稱,Service URL使用這個名稱動態組裝,例如:http://localhost:8080 (必須包括協議,如果埠是標準埠則可以不寫,例如80埠)

可選引數:

  • renew : 指定renew是否為true,有效值為true和false,如果為true則每次請求都產生新的session。預設是false。
  • gateway - 指定是否使用防火牆,有效值是true和false,預設是false。
  • artifactParameterName - 指定request儲存票據的引數名稱,預設是ticket。
  • serviceParameterName - 指定request儲存service的引數名稱,預設是service。

言歸正傳,現在從第一個Filter開始,下面是這個Filter的邏輯過程。


我們發現這個Filter的職責只是判斷是否已經登入,如果沒有登入,則根據配置(gateway)來決定條狀到什麼地方。

我們來看看原始碼中怎麼做的,

 public final void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException {
        // 轉換引數
    	final HttpServletRequest request = (HttpServletRequest) servletRequest;
        final HttpServletResponse response = (HttpServletResponse) servletResponse;
        //從session中取得Assertion
        final HttpSession session = request.getSession(false);
        final Assertion assertion = session != null ? (Assertion) session.getAttribute(CONST_CAS_ASSERTION) : null;
        //如果存在,則說明已經登入,本過濾器處理完成,處理下個過濾器
        if (assertion != null) {
            filterChain.doFilter(request, response);
            return;
        }
        //如果session中沒有Assertion物件,組裝serviceUrl並試著從引數中取得ticket屬性。
        final String serviceUrl = constructServiceUrl(request, response);
        final String ticket = CommonUtils.safeGetParameter(request,getArtifactParameterName());
        final boolean wasGatewayed = this.gatewayStorage.hasGatewayedAlready(request, serviceUrl);
        //如果ticket不為空,或者wasGatewayed為true,則本過濾器處理完成,處理下個過濾器
        if (CommonUtils.isNotBlank(ticket) || wasGatewayed) {
            filterChain.doFilter(request, response);
            return;
        }
        // 定義需要條狀的url地址
        final String modifiedServiceUrl;

        log.debug("no ticket and no assertion found");
        //ticket 為空,並且wasGatewayed也為false,則根據初始化引數gateway的值來組裝跳轉url。
        if (this.gateway) {
            log.debug("setting gateway attribute in session");
            modifiedServiceUrl = this.gatewayStorage.storeGatewayInformation(request, serviceUrl);
        } else {
            modifiedServiceUrl = serviceUrl;
        }

        if (log.isDebugEnabled()) {
            log.debug("Constructed service url: " + modifiedServiceUrl);
        }
        
        //組裝跳轉url
        final String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, getServiceParameterName(), 
        		modifiedServiceUrl, this.renew, this.gateway, this.aspId);

        if (log.isDebugEnabled()) {
            log.debug("redirecting to \"" + urlToRedirectTo + "\"");
        }
        //跳轉到urlToRedirectTo指定的url,如果沒有配置gateway,則跳轉到casServerLoginUrl引數指定的url。
        response.sendRedirect(urlToRedirectTo);
    }