CAS單點登錄原理

概念介紹

  1. CAS介紹
    Central Authentication Service(縮寫CAS)是一種針對萬維網(wǎng)的單點登錄協(xié)議。它的目的是允許一個用戶訪問多個應用程序,而只需提供一次憑證(如用戶名和密碼)。它還允許web應用程序在沒有獲得用戶的安全憑據(jù)(如密碼)的情況下對用戶進行身份驗證。“CAS”也指實現(xiàn)了該協(xié)議的軟件包。
  2. SSO介紹
    Single sign-on(縮寫為 SSO),又譯為單點登錄,一種對于許多相互關連,但是又是各自獨立的軟件系統(tǒng),提供訪問控制的屬性。當擁有這項屬性時,當用戶登錄時,就可以獲取所有系統(tǒng)的訪問權(quán)限,不用對每個單一系統(tǒng)都逐一登錄。這項功能通常是以輕型目錄訪問協(xié)議(LDAP)來實現(xiàn),在服務器上會將用戶信息存儲到LDAP數(shù)據(jù)庫中。相同的,單一退出(single sign-off)就是指,只需要單一的退出動作,就可以結(jié)束對于多個系統(tǒng)的訪問權(quán)限。
  3. 主要特性
    開源的、多協(xié)議的 SSO 解決方案;Protocols:Custom Protocol、CAS、 OAuth、OpenID、RESTful API、SAML1.1、SAML2.0 等。
    支持多種認證機制:Active Directory、JAAS、JDBC、LDAP、X.509 Certificates等;
    安全策略:使用票據(jù)(Ticket)來實現(xiàn)支持的認證協(xié)議;
    支持授權(quán):可以決定哪些服務可以請求和驗證服務票據(jù)(Service Ticket);
    提供高可用性:通過把認證過的狀態(tài)數(shù)據(jù)存儲在TicketRegistry組件中,這些組件有很多支持分布式環(huán)境的實現(xiàn),如:BerkleyDB、Default、EhcacheTicketRegistry、JDBCTicketRegistry、JBOSS TreeCache、JpaTicketRegistry、MemcacheTicketRegistry 等;
    支持多種客戶端:Java、.Net、PHP、Perl、Apache, uPortal 等。
  4. SSO 的主要實現(xiàn)方式
    共享 cookies
    基于共享同域的 cookie 是 Web 剛開始階段時使用的一種方式,它利用瀏覽同域名之間自動傳遞 cookies 機制,實現(xiàn)兩個域名之間系統(tǒng)令牌傳遞問題;另外,關于跨域問題,雖然 cookies本身不跨域,但可以利用它實現(xiàn)跨域的 SSO 。如:代理、暴露 SSO 令牌值等。
    缺點:不靈活而且有不少安全隱患,已經(jīng)被拋棄。
    Broker-based( 基于中間件 )
    這種技術的特點就是,有一個集中的認證和用戶帳號管理的服務器。經(jīng)紀人給被用于進一步請求的電子身份存取。中央數(shù)據(jù)庫的使用減少了管理的代價,并為認證提供一個公共和獨立的 "第三方 " 。例如 Kerberos 、 Sesame 、 IBM KryptoKnight (憑證庫思想 ) 等。 Kerberos是由麻省理工大學發(fā)明的安全認證服務,已經(jīng)被 UNIX 和 Windows 作為默認的安全認證服務集成進操作系統(tǒng)。
    Agent-based (基于代理人)
    在這種解決方案中,有一個自動地為不同的應用程序認證用戶身份的代理程序。這個代理程序需要設計有不同的功能。比如,它可以使用口令表或加密密鑰來自動地將認證的負擔從用戶移開。代理人被放在服務器上面,在服務器的認證系統(tǒng)和客戶端認證方法之間充當一個 " 翻譯 "。例如 SSH 等。
    Token-based
    例如 SecureID,WebID ,現(xiàn)在被廣泛使用的口令認證,比如 FTP 、郵件服務器的登錄認證,這是一種簡單易用的方式,實現(xiàn)一個口令在多種應用當中使用。
    基于網(wǎng)關
    基于 SAML
    SAML(Security Assertion Markup Language ,安全斷言標記語言)的出現(xiàn)大大簡化了 SSO ,并被 OASIS 批準為 SSO 的執(zhí)行標準 。開源組織 OpenSAML 實現(xiàn)了 SAML 規(guī)范。
  5. 登錄流程
    訪問服務:客戶端發(fā)送請求訪問應用系統(tǒng)提供的服務資源。
    定向認證:CAS客戶端會重定向用戶請求到CAS服務器。
    用戶認證:用戶身份認證。
    發(fā)放票據(jù):CAS服務器會產(chǎn)生一個隨機的 Service Ticket 。
    驗證票據(jù):CAS服務器驗證票據(jù) ST 的合法性,驗證通過后,允許客戶端訪問服務。
    傳輸用戶信息:CAS服務器驗證票據(jù)通過后,傳輸用戶認證結(jié)果信息給CAS客戶端。
    流程圖
  6. 相關術語
    票據(jù)
    TGC(Ticket-granting cookie):存放用戶身份認證憑證的 cookie ,在瀏覽器和 CAS Server 間通訊時使用,并且只能基于安全通道傳輸( Https ),是 CAS Server 用來明確用戶身份的憑證;
    ST(Service ticket):服務票據(jù),服務的唯一標識碼 , 由 CAS Server 發(fā)出( Http 傳送),通過客戶端瀏覽器到達業(yè)務服務器端;一個特定的服務只能有一個唯一的 ST ;
    PGT(Proxy-Granting ticket):由 CAS Server 頒發(fā)給擁有 ST 憑證的服務, PGT 綁定一個用戶的特定服務,使其擁有向 CAS Server 申請,獲得 PT 的能力; ST是基于隨機數(shù)生成的 只能使用一次,并且一段時間內(nèi)失效;
    PGTIOU(Proxy-Granting Ticket I Owe You) : 作用是將通過憑證校驗時的應答信息由 CAS Server 返回給 CAS Client ,同時,與該 PGTIOU 對應的 PGT 將通過回調(diào)鏈接傳給 Web 應用。 Web 應用負責維護 PGTIOU 與 PGT 之間映射關系的內(nèi)容表;
    PT(Proxy Ticket):是應用程序代理用戶身份對目標程序進行訪問的憑證;
    TGT(Ticket Granting ticket):票據(jù)授權(quán)票據(jù),由 KDC 的 AS 發(fā)放。即獲取這樣一張票據(jù)后,以后申請各種其他服務票據(jù) (ST) 便不必再向 KDC 提交身份認證信息 (Credentials) ;

其他相關
AS(Authentication service):認證用服務,索取 Credentials ,發(fā)放 TGT ;
TGS(Ticket-granting service):票據(jù)授權(quán)服務,索取 TGT ,發(fā)放 ST ;
KDC( Key Distribution Center ):密鑰發(fā)放中心;

搭建流程

CAS服務端源碼下載地址
CAS服務war包下載
搭建流程比較簡單,這里做下簡單介紹:

  1. 將服務war包下載后放入tomcat中部署運行
    這里有點需要注意下
    CAS默認使用的是HTTPS協(xié)議,如果對安全要求不高,可使用HTTP協(xié)議。下面就是修改一些配置,讓CAS使用HTTP協(xié)議。
  • 修改cas的WEB-INF/deployerConfigContext.xml
    找到下面的配置
<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
p:httpClient-ref="httpClient"/>

這里需要增加參數(shù)p:requireSecure="false",requireSecure屬性意思為是否需要安全驗證,即HTTPS,false為不采用

  • 修改cas的/WEB-INF/spring-configuration/ticketGrantingTicketCookieGenerator.xml
    找到下面配置
<bean id="ticketGrantingTicketCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"
      p:cookieSecure="true"
      p:cookieMaxAge="-1"
      p:cookieName="CASTGC"
      p:cookiePath="/cas" />

參數(shù)p:cookieSecure="true",同理為HTTPS驗證相關,TRUE為采用HTTPS驗證,F(xiàn)ALSE為不采用https驗證。
參數(shù)p:cookieMaxAge="-1",是COOKIE的最大生命周期,-1為無生命周期,即只在當前打開的窗口有效,關閉或重新打開其它窗口,仍會要求驗證。可以根據(jù)需要修改為大于0的數(shù)字,比如3600等,意思是在3600秒內(nèi),打開任意窗口,都不需要驗證。
我們這里將cookieSecure改為false , cookieMaxAge 改為3600

  • 修改cas的WEB-INF/spring-configuration/warnCookieGenerator.xml
    找到下面配置
<bean id="warnCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"
p:cookieSecure="true"
p:cookieMaxAge="-1"
p:cookieName="CASPRIVACY"
p:cookiePath="/cas" />

我們這里將cookieSecure改為false , cookieMaxAge 改為3600

  1. CAS客戶端需要引入客戶端包,添加如下pom:
<!-- cas -->  
<dependency>  
    <groupId>org.jasig.cas.client</groupId>  
    <artifactId>cas-client-core</artifactId>  
    <version>3.3.3</version>  
</dependency>      

配置相應的web.xml:

 <!-- 用于單點退出,該過濾器用于實現(xiàn)單點登出功能,可選配置 -->  
<listener>  
 <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>  
</listener>  
<!-- 該過濾器用于實現(xiàn)單點登出功能,可選配置。 -->  
<filter>  
    <filter-name>CAS Single Sign Out Filter</filter-name>  
   <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>  
</filter>  
<filter-mapping>  
    <filter-name>CAS Single Sign Out Filter</filter-name>  
    <url-pattern>/*</url-pattern>  
</filter-mapping>  
<!-- 該過濾器負責用戶的認證工作,必須啟用它 -->  
<filter>  
    <filter-name>CASFilter</filter-name>       <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>  
    <init-param>  
        <param-name>casServerLoginUrl</param-name>  
        <param-value>http://localhost:9100/cas/login</param-value>  
        <!--這里的server是服務端的IP -->  
    </init-param>  
    <init-param>  
        <param-name>serverName</param-name>  
        <param-value>http://localhost:9001</param-value>
    </init-param>  
</filter>  
<filter-mapping>  
    <filter-name>CASFilter</filter-name>  
    <url-pattern>/*</url-pattern>  
</filter-mapping>  
<!-- 該過濾器負責對Ticket的校驗工作,必須啟用它 -->  
<filter>  
    <filter-name>CAS Validation Filter</filter-name>  
    <filter-class>     org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>  
    <init-param>  
        <param-name>casServerUrlPrefix</param-name>  
        <param-value>http://localhost:9100/cas</param-value>  
    </init-param>  
    <init-param>  
        <param-name>serverName</param-name>  
        <param-value>http://localhost:9001</param-value>
    </init-param>  
</filter>  
<filter-mapping>  
    <filter-name>CAS Validation Filter</filter-name>  
    <url-pattern>/*</url-pattern>  
</filter-mapping>  
<!-- 該過濾器負責實現(xiàn)HttpServletRequest請求的包裹, 比如允許開發(fā)者通過HttpServletRequest的getRemoteUser()方法獲得SSO登錄用戶的登錄名,可選配置。 -->  
<filter>  
    <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>  
    <filter-class>  
        org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>  
</filter>  
<filter-mapping>  
    <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>  
    <url-pattern>/*</url-pattern>  
</filter-mapping>  
<!-- 該過濾器使得開發(fā)者可以通過org.jasig.cas.client.util.AssertionHolder來獲取用戶的登錄名。 比如AssertionHolder.getAssertion().getPrincipal().getName()。 -->  
<filter>  
    <filter-name>CAS Assertion Thread Local Filter</filter-name>       <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>  
</filter>  
<filter-mapping>  
    <filter-name>CAS Assertion Thread Local Filter</filter-name>  
    <url-pattern>/*</url-pattern>  
</filter-mapping> 

原理分析

這里我們通過官方的兩個流程圖來熟悉下其原理:
基礎模式

cas時序圖

代理模式
cas_proxy時序圖

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容