业务系统通过CAS(标准)协议接入IDaaS单点登录

最后更新:2021-12-02

一、CAS 原理

概述

CAS (Central Authentication Service)中央认证服务。CAS(Central Authentication Service)是一款不错的针对 Web 应用的单点登录框架。

CAS 具有以下特点: 开源的企业级单点登录解决方案。 CAS Server 为需要独立部署的 Web 应用。 CAS Client 支持非常多的客户端(这里指单点登录系统中的各个 Web 应用),包括 Java, .Net, PHP, Perl, Apache, uPortal, Ruby 等。

注意:本文中的CAS(标准)协议是指CAS2.0协议

CAS 结构和协议

结构上: CAS 包含两部分

1、CAS Server

CAS Server 负责完成对用户的认证工作, CAS Server 需要独立部署,有不止一种 CAS Server 的实现。 CAS Server 会处理用户名 / 密码等凭证 (Credentials) ,它可能会到数据库检索一条用户帐号信息,也可能在 XML 文件中检索用户密码,对这种方式, CAS 均提供一种灵活但同一的接口 / 实现分离的方式, CAS 究竟是用何种认证方式,跟 CAS 协议是分离的,也就是,这个认证的实现细节可以自己定制和扩展。

2、CAS Client

CAS Client 负责部署在客户端(指 Web 应用),原则上, CAS Client 的部署意味着,当有对本地 Web 应用的受保护资源的访问请求,并且需要对请求方进行身份认证, Web 应用不再接受任何的用户名密码等类似的 Credentials ,而是重定向到 CAS Server 进行认证。 目前, CAS Client 支持(某些在完善中)非常多的客户端,包括 Java 、 .Net 、 ISAPI 、 Php 、 Perl 、 uPortal 、 Acegi 、 Ruby 、 VBScript 等客户端,几乎可以这样说, CAS 协议能够适合任何语言编写的客户端应用。

3、协议

hodu5x_000.png
CAS Client 与受保护的客户端应用部署在一起,以 Filter 方式保护受保护的资源。

对于访问受保护资源的每个 Web 请求,CAS Client 会分析该请求的 Http 请求中是否包含 Service Ticket,如果没有,则说明当前用户尚未登录,于是将请求重定向到指定好的 CAS Server 登录地址,并传递 Service (也就是要访问的目的资源地址),以便登录成功过后转回该地址。

用户输入认证信息,如果登录成功,CAS Server 随机产生一个相当长度、唯一、不可伪造的 Service Ticket,并缓存以待将来验证,之后系统自动重定向到 Service 所在地址,并为客户端浏览器设置一个 Ticket Granted Cookie(TGC),CAS Client 在拿到 Service 和新产生的 Ticket 过后,在第 5 步中与 CAS Server 进行身份验证,以确保 Service Ticket 的合法性。

在该协议中,所有与 CAS 的交互均采用 SSL 协议,确保 ST 和 TGC 的安全性。协议工作过程中会有 2 次重定向的过程,但是 CAS Client 与 CAS Server 之间进行 Ticket 验证的过程对于用户是透明的。

另外,CAS 协议中还提供了 Proxy (代理)模式,以适应更加高级、复杂的应用场景。

CAS(标准)协议常用接口

CAS2.0协议采用XML进行认证,认证流程和CAS1.0总体一致,在认证的URI上有变化,并且CAS2.0提供了代理模式的认证。CAS2.0主要提供的URI包括以下:
/login as credential requestor (GET)
/login as credential acceptor(POST)
/logout
/serviceValidate
/proxyValidate
/proxy

/login as credential requestor (GET)

/login URI通过两种行为运转:一是作为一个凭证索取者,二是作为凭证接收者。根据它对凭证的反应来区分他是作为凭证索取者还是凭证接收者。 如果客户端已经与CAS建立了一个单点登录的session,Web浏览器给CAS一个安全的cookie,里面包含有一个以字符串形式存在的身份信息—TGT(Ticket-Granting Ticket),存储这个身份信息TGT的cookie就被称为票证授予的cookie(TGC- Ticket-Granting Cookie)。如果TGC里面有一个有效的TGT,CAS可以发出一个服务门票(Service Ticket,ST)。 更详细的说明请参考附录的文档。

参数:

service[可选]

客户端尝试访问的应用的标识符。在几乎所有情况下,这将是应用的URL。请注意,作为一个HTTP请求的参数,此URL的值必须是符合RFC 中URL编码的描述。

Renew[可选]

如果此参数设置,单点登录将被绕过。在这种情况下,CAS将要求客户提交证书,不论是否存在一个CAS的单点登录session。这个参数与“gateway”参数不兼容。

Gateway[可选]

如果这个参数设定,CAS将不会向客户端索要凭据。如果客户端有一个已存在的CAS单点登录的session,或者如果单点登录session可以通过非交互方式(i.e. trust authentication,信托认证)建立,CAS可以将客户端请求重定向到“service”参数指定的URL,而且还加上有效的服务票据(Service Ticket,ST)。 如果客户端没有CAS单点登录的session,并且也不可能通过非交互方式建立认证,CAS必须将客户端重定向到“service”参数指定的URL,并且不在URL后面附加“ticket”。如果“service”参数未指定但设置了“gateway”参数,CAS将认为这种行为未定义。在这种情况下推荐:如果两个参数都没有指定,CAS应要求凭据。同样这个参数与“renew”参数不兼容。如果要设置“gateway”参数,推荐设置为“true”。

Simple login example:

https://server/cas/login?service=http%3A%2F%2Fwww.service.com

reponse:

response for single sign-on authentication

如果客户已经建立了一个CAS的单点登录session,客户端将带着自己的HTTP会话cookie来/ Login ,并予以处理。

/login as credential acceptor(POST)

当/login的行为作为凭证索取者时,根据请求的证书的类型响应会有所不同。在大多数情况下,CAS作出的回应是显示登录屏幕要求输入用户名和密码。此网页必须是包括“用户名”,“密码”参数的表单。该表单也可包括 “warn”参数 。如果“service”已被指定为从/login登录,那么“service”也成了登录表单的一个参数,包含着通过/login以后最初的地址。该表单必须通过HTTP POST方法来提交到/login,然后/login就作为凭据接收人。 更详细的说明请参考附录的文档。

参数:

当/login作为凭据接收人时,下面的HTTP请求参数可能被传递到/login。他们都是区分大小写的,它们都必须由/login控制。

service[可选]

客户端尝试访问的应用的URL。成功验证后CAS必须将客户端重定向到这个URL。这是详细讨论了第2.2.4节。

warn[可选]

如果此参数设置,单点登录将不能是透明。客户端必须被提示通过了验证正在转向请求的服务。

当/login作为用户名/密码认证方式的接收人时,下列HTTP请求参数必须被传递到/login。他们都区分大小写。

username[需要]

正在试图登录的客户端的用户名。

password[需要]

正在试图登录的客户端的密码。

It[需要]

登入票证。

response:

/login作为凭证接收者时,下列其中一个回复是它必须提供的。 成功登入:在不将客户端凭证传递到service的情况下,重定向客户端请求到“service”参数指定的网址。这种重定向的结果必须导致用户端向它所请求的服务发出一个GET请求。要求必须包括一个有效的服务票据(Service Ticket,ST),作为HTTP请求的参数通过,它就是“ticket” 。 未能登入:/login将再次作为凭证索取者返回。因此建议在这种情况下,CAS服务器向用户显示错误信息,说明为什么登入失败。

/logout

/logout用于销毁客户端的CAS单点登录会话。TGC被摧毁,随后请求/login将不会取得服务门票(ST),直到用户再次交出主凭证(从而建立了一个新的单点登录session)。 更详细的说明请参考附录的文档。

参数:

url[可选]

如果“url”是指定的,通过“url”参数指定的URL应该是登出页面并且带有描述性文字。

response:

/logout必须展示一个页面,向用户表明现在已经登出。如果“url”请求参数生效,/logout还应提供一个链接到以前登入的URL的链接。

/serviceValidate

/serviceValidate检查ST的有效性,并且返回一个XML片段。 当被请求时,/serviceValidate还必须创造和传出PGT(proxy-granting ticket,代理准许凭证)。如果/serviceValidate收到只是一个PT(proxy ticket,代理凭证),它不可以返回一个成功的验证。CAS推荐:如果/ serviceValidate收到PT,应该在返回的XML响应的错误信息里说明失败的原因,原因是由于PT传递到了/ serviceValidate。也即:/ serviceValidate不能负责校验PT。 更详细的说明请参考附录的文档。

参数:

下面的HTTP请求的参数是/ serviceValidate可以指定的。它们是区分大小写的,必须全部交由/ serviceValidate处理。

service[需要]

服务的标识符,是需要带着ticket访问的服务。

ticket[需要]

/login发出的服务凭证(ST)。

pgtUrl [可选]

代理回调的URL。

renew[可选]

如果这个参数设定,凭证验证将只在ST是来自用户的主认证时才会通过验证,如果ticket是来自SSO session,则验证失败。

response:

/ serviceValidate将返回一个格式化的CASserviceResponse XML。 验证成功:

<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
    <cas:authenticationSuccess>
        <cas:user>username</cas:user>
            <cas:proxyGrantingTicket>PGTIOU-84678-8a9d...
        </cas:proxyGrantingTicket>
    </cas:authenticationSuccess>
</cas:serviceResponse>

验证失败:

<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
    <cas:authenticationFailure code="INVALID_TICKET">
        Ticket ST-1856339-aA5Yuvrxzpv8Tau1cYQ7 not recognized
    </cas:authenticationFailure>
</cas:serviceResponse>

/proxyValidate

/proxyValidate必须执行与/serviceValidate相同的验证任务,并且还要验证PT。/proxyValidate必须能够验证ST和PT。 更详细的说明请参考附录的文档。

参数:

/proxyValidate 参数和/serviceValidate完全相同,请参考/serviceValidate的参数说明。

response:

验证成功:

<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
    <cas:authenticationSuccess>
        <cas:user>username</cas:user>
        <cas:proxyGrantingTicket>
PGTIOU-84678-8a9d...
</cas:proxyGrantingTicket>
        <cas:proxies>
            <cas:proxy>https://proxy2/pgtUrl</cas:proxy>
            <cas:proxy>https://proxy1/pgtUrl</cas:proxy>
        </cas:proxies>
    </cas:authenticationSuccess>
</cas:serviceResponse>

验证失败:

<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
    <cas:authenticationFailure code="INVALID_TICKET">
        ticket PT-1856376-1HMgO86Z2ZKeByc5XdYD not recognized
    </cas:authenticationFailure>
</cas:serviceResponse>

/proxy

/proxy提供到服务的PT,并且这个服务是获取了PGT的,并且可以为后端服务做代理认证。 更详细的说明请参考附录的文档。

参数:

下面的HTTP请求的参数是/proxy必须指定的。他们都区分大小写。

pgt [需要]

代理服务在验证ST和PT后所获取的PGT。

targetService [需要]

后端服务的标识符。请注意,并非所有的后端服务都是web服务,因此这一标识符不会永远是URL。但是不管怎样,这里指定的服务标识符必须匹配访问/proxyValidate时的“service”参数。

response:

验证成功:

<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
    <cas:proxySuccess>
        <cas:proxyTicket>
PT-1856392-b98xZrQN4p90ASrw96c8
</cas:proxyTicket>
    </cas:proxySuccess>
</cas:serviceResponse>

验证失败:

<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
    <cas:proxyFailure code="INVALID_REQUEST">
        'pgt' and 'targetService' parameters are both required
    </cas:proxyFailure>
</cas:serviceResponse>

二、如何配置

IDaaS 中添加 CAS (标准)应用

CAS 标准应用目前只能由 IT 管理员 在应用添加菜单中添加。下面是 IT 管理员的应用添加流程。如果希望使用 CAS(标准)单点登录,可以请管理员进行协助添加和配置。
1、以IT管理员身份登录 IDaaS ,点击添加应用,找到 CAS (标准),点击 添加应用
sso_cas_standard_1.png
添加 CAS(标准)应用第 1 步

2、配置CAS应用
sso_cas_standard_2.png
添加 CAS(标准)应用第 2 步

CAS Client 也就是业务系统需要提供两个参数:
- ServiceNames:CAS Client 发起认证的URL地址。如有您有多个 CAS Client,直接换行添加即可。
- TargetUrl:IDaaS发起单点登录地址。
如果您的CAS Client 在内网,经过反向代理代理到外网。如果您的ServiceName参数值是自动获取的,有可能获取到的ServiceName值是内网的 IP 地址,需要您将ServiceName参数值写成固定的URL地址。

3、启动该应用,并查看该应用详情。
sso_cas_standard_3.png
添加 CAS (标准)应用第 3 步

4、点开查看应用详情后,主要注意 CAS Login URL 和 CAS Server URL Prefix 两个参数以便接下来在 CAS client里面配置使用。
sso_cas_standard_4.png
添加 CAS (标准)应用第 4 步

在 CAS Client 中使用 CAS(标准)应用作为 CAS Server

1、CAS Client DEMO 程序下载地址:https://github.com/aliyun-idaas/idp4-application-cas-demo
2、修改 CAS Client 的配置信息,一般是修改 web.xml 文件。
引用jar包下载地址 : https://github.com/apereo/java-cas-client

3、修改 casServerLoginUrl 参数值,修改为 IDaaS 中创建的 CAS 应用的 CAS Login Url值。
CAS logout url 参数值配置也类似。如果您有使用到,直接复制粘贴IDaaS中CAS应用的CAS Logout URL即可。cas_sta_use_1.png
修改 CAS ServerLoginUrl

4、修改 casServerUrlPrefix参数值,修改为 IDaaS 中创建的 CAS 应用的 CAS validation URL Prefix值。
CAS票据校验地址的URI地址为 public 开头的,与上面的其他地址不一样。
cas_sta_use_2.png
修改 CAS ServerUrlPrefix

CAS validation URL Prefix 为 CAS 票据验证地址的前缀。CAS Client 请求 CAS server 验证 ticket 的完成 URL 请求为 {CAS validation URL Prefix}/serviceValidate?ticket=‘’&service=‘ServiceNames’。
更多的demo使用步骤,请参考demo程序的README.md 文档。

以上为标准CAS协议应用对接。

常见QA