美文网首页
CAS单点登录原理

CAS单点登录原理

作者: 夏目手札 | 来源:发表于2019-05-07 00:34 被阅读0次

    概念介绍

    1. CAS介绍
      Central Authentication Service(缩写CAS)是一种针对万维网的单点登录协议。它的目的是允许一个用户访问多个应用程序,而只需提供一次凭证(如用户名和密码)。它还允许web应用程序在没有获得用户的安全凭据(如密码)的情况下对用户进行身份验证。“CAS”也指实现了该协议的软件包。
    2. SSO介绍
      Single sign-on(缩写为 SSO),又译为单点登录,一种对于许多相互关连,但是又是各自独立的软件系统,提供访问控制的属性。当拥有这项属性时,当用户登录时,就可以获取所有系统的访问权限,不用对每个单一系统都逐一登录。这项功能通常是以轻型目录访问协议(LDAP)来实现,在服务器上会将用户信息存储到LDAP数据库中。相同的,单一退出(single sign-off)就是指,只需要单一的退出动作,就可以结束对于多个系统的访问权限。
    3. 主要特性
      开源的、多协议的 SSO 解决方案;Protocols:Custom Protocol、CAS、 OAuth、OpenID、RESTful API、SAML1.1、SAML2.0 等。
      支持多种认证机制:Active Directory、JAAS、JDBC、LDAP、X.509 Certificates等;
      安全策略:使用票据(Ticket)来实现支持的认证协议;
      支持授权:可以决定哪些服务可以请求和验证服务票据(Service Ticket);
      提供高可用性:通过把认证过的状态数据存储在TicketRegistry组件中,这些组件有很多支持分布式环境的实现,如:BerkleyDB、Default、EhcacheTicketRegistry、JDBCTicketRegistry、JBOSS TreeCache、JpaTicketRegistry、MemcacheTicketRegistry 等;
      支持多种客户端:Java、.Net、PHP、Perl、Apache, uPortal 等。
    4. SSO 的主要实现方式
      共享 cookies
      基于共享同域的 cookie 是 Web 刚开始阶段时使用的一种方式,它利用浏览同域名之间自动传递 cookies 机制,实现两个域名之间系统令牌传递问题;另外,关于跨域问题,虽然 cookies本身不跨域,但可以利用它实现跨域的 SSO 。如:代理、暴露 SSO 令牌值等。
      缺点:不灵活而且有不少安全隐患,已经被抛弃。
      Broker-based( 基于中间件 )
      这种技术的特点就是,有一个集中的认证和用户帐号管理的服务器。经纪人给被用于进一步请求的电子身份存取。中央数据库的使用减少了管理的代价,并为认证提供一个公共和独立的 "第三方 " 。例如 Kerberos 、 Sesame 、 IBM KryptoKnight (凭证库思想 ) 等。 Kerberos是由麻省理工大学发明的安全认证服务,已经被 UNIX 和 Windows 作为默认的安全认证服务集成进操作系统。
      Agent-based (基于代理人)
      在这种解决方案中,有一个自动地为不同的应用程序认证用户身份的代理程序。这个代理程序需要设计有不同的功能。比如,它可以使用口令表或加密密钥来自动地将认证的负担从用户移开。代理人被放在服务器上面,在服务器的认证系统和客户端认证方法之间充当一个 " 翻译 "。例如 SSH 等。
      Token-based
      例如 SecureID,WebID ,现在被广泛使用的口令认证,比如 FTP 、邮件服务器的登录认证,这是一种简单易用的方式,实现一个口令在多种应用当中使用。
      基于网关
      基于 SAML
      SAML(Security Assertion Markup Language ,安全断言标记语言)的出现大大简化了 SSO ,并被 OASIS 批准为 SSO 的执行标准 。开源组织 OpenSAML 实现了 SAML 规范。
    5. 登录流程
      访问服务:客户端发送请求访问应用系统提供的服务资源。
      定向认证:CAS客户端会重定向用户请求到CAS服务器。
      用户认证:用户身份认证。
      发放票据:CAS服务器会产生一个随机的 Service Ticket 。
      验证票据:CAS服务器验证票据 ST 的合法性,验证通过后,允许客户端访问服务。
      传输用户信息:CAS服务器验证票据通过后,传输用户认证结果信息给CAS客户端。
      流程图
    6. 相关术语
      票据
      TGC(Ticket-granting cookie):存放用户身份认证凭证的 cookie ,在浏览器和 CAS Server 间通讯时使用,并且只能基于安全通道传输( Https ),是 CAS Server 用来明确用户身份的凭证;
      ST(Service ticket):服务票据,服务的唯一标识码 , 由 CAS Server 发出( Http 传送),通过客户端浏览器到达业务服务器端;一个特定的服务只能有一个唯一的 ST ;
      PGT(Proxy-Granting ticket):由 CAS Server 颁发给拥有 ST 凭证的服务, PGT 绑定一个用户的特定服务,使其拥有向 CAS Server 申请,获得 PT 的能力; ST是基于随机数生成的 只能使用一次,并且一段时间内失效;
      PGTIOU(Proxy-Granting Ticket I Owe You) : 作用是将通过凭证校验时的应答信息由 CAS Server 返回给 CAS Client ,同时,与该 PGTIOU 对应的 PGT 将通过回调链接传给 Web 应用。 Web 应用负责维护 PGTIOU 与 PGT 之间映射关系的内容表;
      PT(Proxy Ticket):是应用程序代理用户身份对目标程序进行访问的凭证;
      TGT(Ticket Granting ticket):票据授权票据,由 KDC 的 AS 发放。即获取这样一张票据后,以后申请各种其他服务票据 (ST) 便不必再向 KDC 提交身份认证信息 (Credentials) ;

    其他相关
    AS(Authentication service):认证用服务,索取 Credentials ,发放 TGT ;
    TGS(Ticket-granting service):票据授权服务,索取 TGT ,发放 ST ;
    KDC( Key Distribution Center ):密钥发放中心;

    搭建流程

    CAS服务端源码下载地址
    CAS服务war包下载
    搭建流程比较简单,这里做下简单介绍:

    1. 将服务war包下载后放入tomcat中部署运行
      这里有点需要注意下
      CAS默认使用的是HTTPS协议,如果对安全要求不高,可使用HTTP协议。下面就是修改一些配置,让CAS使用HTTP协议。
    • 修改cas的WEB-INF/deployerConfigContext.xml
      找到下面的配置
    <bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
    p:httpClient-ref="httpClient"/>
    

    这里需要增加参数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" />
    

    参数p:cookieSecure="true",同理为HTTPS验证相关,TRUE为采用HTTPS验证,FALSE为不采用https验证。
    参数p:cookieMaxAge="-1",是COOKIE的最大生命周期,-1为无生命周期,即只在当前打开的窗口有效,关闭或重新打开其它窗口,仍会要求验证。可以根据需要修改为大于0的数字,比如3600等,意思是在3600秒内,打开任意窗口,都不需要验证。
    我们这里将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:

     <!-- 用于单点退出,该过滤器用于实现单点登出功能,可选配置 -->  
    <listener>  
     <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>  
    </listener>  
    <!-- 该过滤器用于实现单点登出功能,可选配置。 -->  
    <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>  
    <!-- 该过滤器负责实现HttpServletRequest请求的包裹, 比如允许开发者通过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>  
    <!-- 该过滤器使得开发者可以通过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时序图

    相关文章

      网友评论

          本文标题:CAS单点登录原理

          本文链接:https://www.haomeiwen.com/subject/bdcymqtx.html