You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Spring Security CAS客户端配置:获取自定义属性与代理票据问题求助

CAS客户端配置Proxy Granting Ticket及自定义属性的问题解析

一、CAS服务器为何不返回Proxy Granting Ticket?

首先得明确CAS的Proxy Granting Ticket(PGT)生成逻辑:CAS服务器只会在客户端明确声明了Proxy Callback Url的情况下,才会生成并返回PGT。PGT是用于后续代理认证的凭证,只有当客户端告诉CAS服务器“我有一个可以接收PGT回调的地址”时,CAS才会触发PGT的生成流程。

你提到的“未添加ProxyCallbackUrl时,CAS响应中没有proxyGrantingTicket标签”是正常行为——因为没有请求PGT,CAS服务器不会生成这个票据。而你遇到的“无法从principal中获取自定义属性”,本质是因为你使用的Cas20ServiceTicketValidator不支持解析包含PGT和属性的代理响应结构,换成Cas20ProxyTicketValidatorCas30ProxyTicketValidator后,配合Proxy Callback Url的配置,服务器才会在响应中包含属性信息,解析器也能正确处理这些属性。

二、如何正确配置客户端的Proxy Callback Url?

你遇到的INVALID_PROXY_CALLBACK错误,核心原因是CAS服务器不信任你的回调地址,或者无法访问到这个地址,可以按以下步骤排查修复:

1. 在CAS服务器上信任你的Proxy Callback Url

CAS服务器会校验所有请求的代理回调地址,只有在信任列表中的地址才会被允许。你需要:

  • 找到CAS服务器的服务注册配置(比如CAS 5+常用JSON格式的服务注册表),给你的客户端服务条目添加allowedProxyCallbackUrls属性,把http://localhost:9000/login/cas/proxyreceptor添加进去。
  • 确保地址完全匹配:协议(http/https)、主机名、端口、路径都要和客户端配置的一致,不能有多余的斜杠、大小写差异。

2. 确保CAS服务器能访问到回调地址

  • 如果是本地测试,CAS和客户端都在本地机器,localhost:9000是可以访问的;但如果CAS部署在远程服务器,客户端在本地,CAS服务器无法访问localhost,这时候需要换成客户端的公网IP/可访问域名,同时开放9000端口的防火墙权限。
  • 可以在CAS服务器所在机器上,用curl http://localhost:9000/login/cas/proxyreceptor测试,只要能得到200响应(Spring Security的Proxy Receptor会返回空或特定响应),就说明地址可达。

3. 客户端配置的细节校验

  • 务必使用Cas20ProxyTicketValidatorCas30ProxyTicketValidator,不要用普通的Cas20ServiceTicketValidator——后者不支持代理相关的响应解析。
  • 确保ProxyGrantingTicketStorage是同一个实例:比如定义一个@BeanInMemoryProxyGrantingTicketStorage,同时注入到ticketValidatorcasAuthenticationFilter中,这样两者能共享PGT数据。
  • ProxyReceptorUrl要和Proxy Callback Url的路径完全一致:比如你的回调地址路径是/login/cas/proxyreceptor,那么casAuthenticationFilterProxyReceptorUrl就必须设置为这个值,不能有路径差异。

补充:自定义属性的获取

当上述配置都正确后,你可以通过以下方式获取CAS下发的自定义属性:

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication.getPrincipal() instanceof CasAuthenticatedPrincipal) {
    CasAuthenticatedPrincipal principal = (CasAuthenticatedPrincipal) authentication.getPrincipal();
    Map<String, Object> attributes = principal.getAttributes();
    // 从attributes中获取你需要的自定义属性
}

如果还是拿不到属性,要检查CAS服务器的属性释放策略,确保需要的属性已经被配置为允许返回给客户端。

内容的提问来源于stack exchange,提问作者Sébastien Ragons

火山引擎 最新活动