1. 程式人生 > >(五)SSO之CAS框架單點登入, session超時, ajax連結處理

(五)SSO之CAS框架單點登入, session超時, ajax連結處理

1 錯誤場景                                  

部署問題:用nginx封裝,service攜帶不過來。

 2 cas 針對session超時設定               

cas對於session超時設定,可以設定檔案cas\WEB-INF\spring-configuration\ticketExpirationPolicies.xml 進行設定,如下所示:

<bean id="grantingTicketExpirationPolicy" class="org.jasig.cas.ticket.support.RememberMeDelegatingExpirationPolicy">
       <property name="sessionExpirationPolicy">
           <bean class="org.jasig.cas.ticket.support.TimeoutExpirationPolicy">
           	<constructor-arg index="0" value="20000" />
                	</bean>
       </property>
	<bean id="serviceTicketExpirationPolicy" class="org.jasig.cas.ticket.support.MultiTimeUseOrTimeoutExpirationPolicy">
		<!-- This argument is the number of times that a ticket can be used before its considered expired. -->
		<constructor-arg
			index="0"
			value="1" />
		
		<!-- This argument is the time a ticket can exist before its considered expired.  -->
		<constructor-arg
			index="1"
			value="20000" />
	</bean>


上述兩個bean中,設定為20000毫秒(設定超時單位為毫秒),上述另個bean的機制就如同session機制一樣,當用戶沒有與伺服器的互動超過20秒,點選url,便會自動轉到登入介面。單只是設定這一點是不夠的,會有問題的。

問題:當你的專案中也有對session的設定,以及對session時間的設定的時候,只設置cas的session超時是不管事的。

 3 配置完畢,對於ajax請求出現的錯誤

問題的解決:所以我們需要把專案中session超時的時間和cas session超時的時間設定為一致,因為cas對session超時的處理,是在cas-client-core-3.2.1.jar 包中,而cas的客戶端是和專案放在一起的,所以對session處理機制是一樣的。

當然上述的處理一般情況下是沒有問題的,但當遇到ajax請求,就不可以了,會報如下錯誤:

千萬別被Origin矇蔽,開始定位錯誤定位在跨域問題,因為網上查詢說也是跨域問題,而實際上對於非ajax請求,cas攔截處理後是可以跳轉到登入頁面的,這說明了是可以請求給cas的,只不過cas對ajax的請求無法做出session失效的處理,這怎麼辦呢?只能去改CAS原始碼了。不知道是cas矮,還是自己太矮了。。。

 4 修改CAS原始碼,解決上述問題

經過檢視錯誤日誌,找到cas列印日誌的地方,找到cas處理session的方法,修改的是/CAS_Client/src/org/jasig/cas/client/authentication/AuthenticationFilter.java這個java類。修改的doFilter方法如下所示。

  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;
        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;
        }

        final String serviceUrl = constructServiceUrl(request, response);
        final String ticket = CommonUtils.safeGetParameter(request,getArtifactParameterName());
        final boolean wasGatewayed = this.gatewayStorage.hasGatewayedAlready(request, serviceUrl);

        if (CommonUtils.isNotBlank(ticket) || wasGatewayed) {
            filterChain.doFilter(request, response);
            return;
        }

        final String modifiedServiceUrl;

        log.debug("no ticket and no assertion found");
        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);
        }
        
        final String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway);

        if (log.isDebugEnabled()) {
            log.debug("redirecting to \"" + urlToRedirectTo + "\"");
        }
        
        log.debug("判斷拼接的過程,引數, 最終拼接好的地址為: \"" + urlToRedirectTo + "\"");
        
        //response.sendRedirect(urlToRedirectTo);
        String url = request.getRequestURL().toString();
        log.debug("url------request.getRequestURL().toString()=---------:" + url);
        String contextPath = request.getContextPath();
        log.debug("contextPath ---------request.getContextPath()=-------:" + contextPath);
        
        url = url.substring(0, (url.indexOf(contextPath)+contextPath.length()));
        log.debug("url = ------session消失,擷取到專案的url---" + url);
        String urls = urlToRedirectTo;
        
        //判斷是否是第一次轉到.
        if("".equals(url)||url==null||url.length()==0){
        	
        	log.debug("url--第一次為空,不擷取-----" + url);
        	urls = urlToRedirectTo;
        	//response.sendRedirect(urlToRedirectTo);
        }else{
        	urls = urls.substring(0, (urls.indexOf("service=")+8)) + URLEncoder.encode(url,"UTF-8");
        }
        
        log.debug("urls --最終輸入到瀏覽器的地址是-----------" + urls);
        
		response.setContentType("text/html;charset=UTF-8");
		response.getWriter().write("<script languge='javascript'>window.location.href='"+urls+"/'</script>");
    }

這樣不但解決了cas對ajax地址處理,並且解決了另一個問題,因為最初的改動不是上述的程式碼,中間出現了一個小插曲,部署的時候出現的bug,登入時service引數攜帶不過來。當我們把專案部署到linux上時,用nginx代理,並配置tomcat的sever.xml檔案封裝專案名稱, 則樣,域名“封裝”了ip+埠號+專案名稱,使用者不需要再輸入專案名稱了。所以程式碼中對使用者第一次登入做判斷,判斷是否是第一次登入還是session失效呼叫的這個方法,這樣就解決了nginx代理出現的問題了。

 5  總結                                       

錯誤未出現時:黑暗前的黎明

錯誤出現時:電閃雷鳴

錯誤解決中:時間就像過火車

錯誤解決完畢:原來神馬都是浮雲啊

方法上:這個過程就像是你回到家發現鑰匙丟在路上了,找到開門的鑰匙,要一步一個腳印的去找,對了一步再進行下一步,到底是哪一步找到了鑰匙?到底是哪一步,找到了錯誤?要相信,你永遠被錯誤幹不掉,只是你又幹掉了錯誤。是一次又一次的錯誤在改變你,而錯誤永遠變不了,就像倉央嘉措的那首情詩,《見或不見》.

bug對我的感情上:你見,或者不見我;我就在那裡;不悲不喜;你念,或者不念我;情就在那裡;不來不去;你愛,或者不愛我;愛就在那裡;不增不減;你跟,或者不跟我;我的手就在你的手裡;不捨不棄;來我的懷裡;或者讓我住進你的心裡;默然,相愛;寂靜,歡喜;

相關推薦

()SSOCAS框架登入, session超時, ajax連結處理

1 錯誤場景                                   部署問題:用nginx封裝,service攜帶不過來。  2 cas 針對session超時設定                cas對於session超時設定,可以設定檔案cas\WEB

登入,session超時, ajax連結處理

1 錯誤場景                                   部署問題:用nginx封裝,service攜帶不過來。  2 cas 針對session超時設定                cas對於session超時設定,可以設定檔案cas\WEB-INF\spring-conf

CAS框架登入原理解析

單點登入:Single Sign On,簡稱SSO,SSO使得在多個應用系統中,使用者只需要登入一次就可以訪問所有相互信任的應用系統。 CAS框架:CAS(Central Authentication Service)是實現SSO單點登入的框架。 CSA

基於CAS登入SSO[5]: 基於Springboot實現CAS客戶端的前後端分離

基於CAS的單點登入SSO[5]: 基於Springboot實現CAS客戶端的前後端分離 作者:家輝,日期:2017-08-24 CSDN部落格: http://blog.csdn.net/gobitan 摘要:現在大部分系統的開發都已經

基於CAS登入SSO[4]: 加入兩個CAS客戶端測試登入

基於CAS的單點登入SSO[4]: 加入兩個CAS客戶端測試單點登入 作者:家輝,日期:2017-08-22 CSDN部落格: http://blog.csdn.net/gobitan 摘要:本系列的前三篇文章分別搭建了基於CAS的單點登入伺服器,並讓伺

基於CAS登入SSO[3]: 改造cas-overlays-template支援Redis儲存Ticket

基於CAS的單點登入SSO[3]: 改造cas-overlays-template支援Redis儲存Ticket 作者:家輝,日期:2017-08-20 CSDN部落格: http://blog.csdn.net/gobitan 摘要:預

CAS實現登入SSO

什麼是單點登入 單點登入(Single Sign On),簡稱為 SSO,是目前比較流行的企業業務整合的解決方案之一。SSO的定義是在多個應用系統中,使用者只需要登入一次就可以訪問所有相互信任的應用系統。 我們目前的系統存在諸多子系統,而這些子系統是分別部署在不

CAS實現登入SSO執行原理探究(終於明白了)

一、不落俗套的開始 1、背景介紹 單點登入:Single Sign On,簡稱SSO,SSO使得在多個應用系統中,使用者只需要登入一次就可以訪問所有相互信任的應用系統。 CAS框架:CAS(Central Authentication Service)是實現S

CAS實現登入sso)搭建流程 伺服器端搭建

一、簡介 1、cas是有耶魯大學研發的單點登入伺服器 2、所用環境 ·        Linux系統 ·        To

CAS Server 登入SSO 認證服務搭建部署

部署環境 1 下載CAS Server 4.0 :https://github.com/apereo/cas/releases/tag/v4.0.0     這裡選擇4.0是因為其有官方release版本的cas-server-webapp-4.0.0.war。

基於CAS實現登入SSO):CAS+LDAP實現登入認證

[一]、概述 CAS是N個系統的中心認證入口,而貫穿多個系統的使用者資訊是共用的,應該被單獨維護,而這些資訊可能屬於不用的系統,不用的組織,不用的國家,從而形成了樹形結構,而使用關係型資料庫維護樹形結構資訊是它的弱點,這就是本文CAS和LDAP整合的初衷。 本來主要

據說是springboot下實現cas登入(但是我總感覺是MVC)----基於前後臺分離的

一、前言 前後端分離開發是目前軟體開發的主流,大大提高了開發效率  但也帶來了很多不方便之處。 1、優點:  ① 傳統全棧開發的 MVC 模式將不適合,後臺採取 MVP 面向介面程式設計,耦合度大大降低 2、缺點:  ① 跨域問題不勝其擾 3、原則:&n

CAS登入) 引起的亂碼問題

最近專案整合CAS單點登入後,又出現了亂碼問題。修改Tomcat編碼,不起作用;WEB.XML配置字符集過濾filter不起作用,想來想去,問題可能出現在CAS上。 經過測試,原來是字元過濾filter配置在了CAS的下面。 修改為如下即可: <!

CAS登入和oauth2的最大區別

oauth2則是保障服務端的使用者資源的安全 CAS客戶端要獲取的最終資訊是,這個使用者到底有沒有許可權訪問我(CAS客戶端)的資源。 oauth2獲取的最終資訊是,我(oauth2服務提供方)的使用者的資源到底能不能讓你(oauth2的客戶端)訪問 CAS的單

SSOCAS整合自定義登入頁面

前言: 一:替換頁面 找到CAS服務端中WEB-INF/view/jsp/default/ui/下的casLoginView.jsp頁面,此頁面為CAS預設的登入頁面,將自定義的頁面取名也叫casLoginView.jsp進行頁面替換,替換前先把預設的備份一份。 替

cas實現登入-應用場景和完整配置

Cas 簡介 1、什麼是CAS CAS是一個單點登入(SSO)的框架。單點登入是目前比較流行的服務於企業業務整合的解決方案之一,SSO使得在多個應用系統中,使用者只需要登入一次就可以訪問所有相互信任的應用系統。 2、CAS的主要結構 CAS包括兩部分:

CAS 實現登入oos(2)

  前面已經介紹了CAS伺服器的搭建,詳情見:搭建CAS單點登入伺服器。然而前面只是簡單地介紹了伺服器的搭建,其驗證方式是原始的配置檔案的方式,這顯然不能滿足日常的需求。下面介紹下通過mysql資料庫認證的方式。   一、CAS認證之mysql資料庫認證   1、在mysql中新建一個cas資料庫並建立us

SSO-C#跨域登入(一)

開篇就是定義Model,資料為先: public class Something { public const string CookieName = "User"; public const double TimeOut = 1

Spring Security 4.0 CAS實現登入

1、各framework版本資訊       JDK 8       Tomcat 7       SpringMVC-4.2.0.RELEASE       Spring Security 4.2.0.RELEASE       CAS-Client 3.3.3       CAS-Serv

SSO登入 & Session共享

單點登入 背景: Tomcat叢集可能因為兩次訪問的Session不一致導致登入失敗,無法訪問後續頁面; 解決可以通過tomcat互相進行Session共享實現,但是這僅僅試用於小叢集; 如果叢集變大,就會有大量Session進行互相共享,負載很大;