程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 基於CAS實現單點登錄(SSO):cas client端的退出問題

基於CAS實現單點登錄(SSO):cas client端的退出問題

編輯:C++入門知識

自從CAS 3.4就很好的支持了單點注銷功能,配置也很簡單。

之前版本因為在CAS服務器通過HttpClient發送消息時並未指定為POST方式,所以在CAS客戶端的注銷Filter中沒有收到POST請求(要知道Filter只對Post請求起作用),也就沒有做session銷毀處理。

兩個業務系統APP1和APP2

在沒有配置單點退出時,效果是這樣子的

1:登錄APP1,然後經過CAS認證後進入APP1,再訪問APP2無需要認證

2:在APP1中連接到cas的logout地址,現象注銷成功界面,然後再訪問APP1,還是可以進去的,因為APP1將用戶的登錄票據存入了session。

那麼實現了單點退出後的效果應該是這樣子的:

1:登錄APP1,然後經過CAS認證後進入APP1,再訪問APP2無需要認證

2:用戶在APP1或者APP2點擊注銷,顯示CAS的注銷成功頁面,然後再訪問APP1或者APP2都需要再次認證。

具體配置為,在APP1和APP2的web.xml文件中增加:

  
        org.jasig.cas.client.session.SingleSignOutHttpSessionListener  
  
      
   
       CAS Single Sign Out Filter  
       org.jasig.cas.client.session.SingleSignOutFilter  
    
  
    CAS Single Sign Out Filter  
    /*  
   


注銷的Filter要在其它Filter之前,界面的注銷連接到CAS的logout地址,如http://localhost:8080/cas/logout

SingleSignOutFilter,主要是在有ticket參數的時候,將session放到sessionMappingStorage,如果參數中存在logoutRequest,則注銷session,那什麼時候去注銷sessionMappingStorage的東西呢?這是靠SingleSignOutHttpSessionListener來實現的,當有session被銷毀的時候,觸發將sessionMappingStorage中對應sessionid中的數據刪除。

所以在配置單點登出的時候,一定要配置這個監聽器,否則客戶端很容易導致內存溢出的。讓我們先來看看SingleSignOutFilter的整體邏輯。

\

那麼這個是在什麼時候會觸發呢,這個是在你登陸的任意客戶端,調用https://localhost:8080/logout,這個取得cookie裡面的TGT數據,找到TGT中關聯的所有ST對應的地址(即多個cas client),向每個地址方式一個http請求,並傳遞logoutRequest參數。

來看看源代碼是怎麼實現的:

public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException {  
      // 轉換參數  
    final HttpServletRequest request = (HttpServletRequest) servletRequest;  
    //判斷參數中是否具有artifactParameterName屬性指定的參數名稱,默認是ticket  
      if (handler.isTokenRequest(request)) {  
        // 如果存在,在本地sessionMappingStorage中記錄session。  
          handler.recordSession(request);   
      } else if (handler.isLogoutRequest(request)) {//判斷是否具有logoutParameterName參數指定的參數,默認參數名稱為logoutRequest  
        // 如果存在,則在sessionMappingStorage中刪除記錄,並注銷session。  
        handler.destroySession(request);  
          // 注銷session後,立刻停止執行後面的過濾器  
          return;  
      } else {  
          log.trace("Ignoring URI " + request.getRequestURI());  
      }  
      //條件都不滿足,繼續執行下面的過濾器  
      filterChain.doFilter(servletRequest, servletResponse);  
  }  


如果直接訪問CAS的logout話,會出現注銷成功頁面,其實大部分情況下這個頁面是沒有必要的,更多的需求可能是退出後顯示登錄頁面,並且登錄成功後還是會進入到之前的業務系統,那麼可以修改cas-servlet.xml文件,在"logoutController"的bean配置中增加屬性“followServiceRedirects”,設置為“true”,然後在業務系統的注銷連接中加入"service參數",值為業務系統的絕對URL,這樣就OK了,如你的業務系統URL為:http://localhost:8080/casClient,那麼注銷URL就為:http://localhost:8080/cas/logout?service=http://localhost:8080/casClient

如果出現這種現象:訪問過http://localhost:8080/cas/logout之後不關浏覽器,還是能訪問我的應用

可能因為:

1:你的CAS服務器將cookie設置成了浏覽器有效,那麼表示如果浏覽器不關閉,則一直有效。

在WEB-INF/spring-configuration/ticketGrantingTicketCookieGenerator.xml中設置cookie有效期,默認配置cookie有效期為-1

2:你的應用中注銷的filter-mapping沒有放在所有mapping之前

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved