- 后端
- 认证鉴权
- 单点登录
【免费下载链接】cas
Apereo CAS - Identity & Single Sign On for all earthlings and beyond.
CAS 作为 SAML2 身份提供者(IdP)时,需要向各服务提供者(SP)暴露一份自描述的 IdP 元数据。本文围绕 CAS 官方的 SAML2 Metadata Management 文档,讲清/idp/metadata三个端点的行为语义、service参数如何按服务注册表解析 IdP 元数据覆盖项,以及基于文件系统的元数据生成、存储与按服务(per-service)覆盖目录的完整规则,并结合cas-server-support-saml-idp/cas-server-support-saml-idp-web模块的源码,给出端点背后的调用链、产物文件命名与签名生成逻辑,帮助你在部署和密钥轮换场景下正确配置 CAS IdP 元数据。
一、CAS 提供的 SAML2 元数据端点
CAS 通过以下三个端点处理 SAML2 元数据的生成与分发:
/idp/metadata/idp/metadata/signingCertificate/idp/metadata/encryptionCertificate
收到 GET 请求时,端点会展示 CAS IdP 的 SAML2 元数据:如果元数据已经存在且已生成,则直接展示;如果元数据缺失,则会自动生成一份。CAS 配置决定了元数据文件和密钥生成、存储在哪里。
需要特别注意:端点可以接受一个service参数,其取值可以是服务的实体标识(entity id)或服务的数字标识(id)。该参数会与 CAS 服务注册表(service registry)进行匹配,使端点能够计算并合并针对该服务定义的任何 IdP 元数据覆盖项。
源码印证:端点由哪个组件提供
这三个端点在 SamlIdPMetadataController 中实现。其核心方法generateMetadataForIdp的处理流程(见 SamlIdPMetadataController.java#L57-L78)为:
- 先通过
getRegisteredServiceIfAny(service)解析出service参数对应的SamlRegisteredService(可空); - 调用
metadataAndCertificatesGenerationService.generate(registeredService)确保元数据存在(不存在则生成); - 再通过
samlIdPMetadataLocator.resolveMetadata(registeredService)定位元数据资源,将内容以text/xml;charset=UTF-8写出到响应。
其中getRegisteredServiceIfAny(SamlIdPMetadataController.java#L116-L124)正是“service参数按实体 id 或数字 id 匹配服务注册表”这一文档描述的源码实现:若参数是纯数字,则按数字 id 查找;否则将其构造为WebApplicationService再按服务定义查找,最终只接受SamlRegisteredService类型的注册服务。两个证书端点/signingCertificate、/encryptionCertificate则以text/plain分别返回签名证书和加密证书的原文。
端点路径本身由常量 SamlIdPConstants.java#L28 中的ENDPOINT_IDP_METADATA = BASE_ENDPOINT_IDP + "/metadata"定义。单元测试 SamlIdPMetadataControllerTests 覆盖了对这三个端点的 GET 访问断言,可作为端点行为的验证依据。
文档中还提到可以使用 samltool 之类的第三方工具试验元数据生成流程、产出示例元数据供审阅学习(该工具为外部在线服务,此处仅作流程说明)。
二、文件系统策略:默认生成位置与产物命名
身份提供者元数据还可以通过若干策略来管理,文件系统是默认策略:SAML2 IdP 元数据默认在磁盘上生成。生成的(或找到的)签名/加密密钥等产物的内容,可以通过 CAS 配置安全机制进行加密,具体方式参见 CAS 配置安全 文档。
核心配置项
官方文档通过cas.authn.saml-idp.metadata.core与cas.authn.saml-idp.metadata.file-system两组前缀暴露核心配置。结合源码中的配置模型 SamlIdPMetadataProperties.java(@RequiresModule(name = "cas-server-support-saml-idp"),即需要引入cas-server-support-saml-idp模块)可以确认,file-system组只有两个关键项(见 FileSystemSamlMetadataProperties.java):
| 配置项 | 默认值 | 说明 |
|---|---|---|
cas.authn.saml-idp.metadata.file-system.location | file:/etc/cas/saml | SAML 元数据与签名/加密密钥所在的目录位置,该目录用于存放配置文件 |
cas.authn.saml-idp.metadata.file-system.sign-metadata | false | 是否对生成在磁盘上的元数据做数字签名,签名使用 SAML2 IdP 的签名证书与签名密钥 |
core组的关键项定义在 CoreSamlMetadataProperties.java:
| 配置项 | 默认值 | 说明 |
|---|---|---|
cas.authn.saml-idp.metadata.core.cache-expiration | PT24H | 元数据的缓存时长(Duration 格式) |
cas.authn.saml-idp.metadata.core.key-size | 4096 | 生成初始密钥对(承载 SAML2 元数据的私钥/公钥)时的密钥长度,仅在需要生成密钥时相关 |
cas.authn.saml-idp.metadata.core.certificate-algorithm | SHA512withRSA | 生成 SAML2 身份提供者证书时使用的算法类型/名称,仅在需要生成证书时相关 |
此外,core组还有元数据缓存大小、是否要求有效元数据、SSO/SLO 各绑定(POST、SimpleSign、REDIRECT、SOAP)开关等生成流程控制项,完整清单可通过cas.authn.saml-idp.metadata.core前缀在 CAS 文档属性表中查询。
产物文件命名:从源码看默认约定
默认的磁盘产物并非一个笼统的“目录”——从 FileSystemSamlIdPMetadataLocator 的实现看,CAS 在元数据目录中管理 5 个具名产物:
| 产物 | 文件名 |
|---|---|
| IdP 元数据 | idp-metadata.xml |
| 签名证书 | idp-signing.crt |
| 签名密钥 | idp-signing.key |
| 加密证书 | idp-encryption.crt |
| 加密密钥 | idp-encryption.key |
该类还持有CipherExecutor参数用于支持上述配置安全加密机制:若磁盘文件内容是加密的,读取时会经由resolveContentToResource解密后再使用;同时它会维护一份元数据缓存(Caffeine),对应core.cache-expiration/core.cache-maximum-size配置。
生成时机与签名逻辑
从 FileSystemSamlIdPMetadataGenerator 的源码结构看:
afterPropertiesSet()会在 Spring 容器初始化阶段调用generate(Optional.empty()),即启动时若元数据缺失会自动生成,这与端点“元数据缺失则自动生成”的行为一致;- 生成证书/密钥时,若
idp-signing.crt/idp-signing.key(或加密一对)已存在,会先删除旧文件再重写(writeCertificateAndKey中的处理),意味着重新生成会替换既有密钥对; - 当
sign-metadata为true时,writeMetadata会用签名证书 + 签名密钥对生成的元数据做数字签名后再写入idp-metadata.xml,签名参数为 RSA-SHA256 签名算法、SHA-256 摘要、C14N 排除规范化(见 FileSystemSamlIdPMetadataGenerator.java#L54-L103)。
相关行为在测试用例 FileSystemSamlIdPMetadataGeneratorTests 与 FileSystemSamlIdPMetadataLocatorTests 中有对应验证。
三、Per Service:按服务覆盖 IdP 元数据
IdP 元数据、证书和密钥还可以在按服务(per-service)的粒度上定义,用以覆盖全局默认值。
覆盖目录的命名规则
对于需要通过文件系统管理的、仅适用于某个服务定义的元数据产物,必须存放在以服务定义名称和数字标识命名的目录中,且该目录位于全局元数据目录之内。例如:如果全局元数据产物在磁盘/etc/cas/config/saml/metadata下管理,那么对于名称配置为SampleService、id 为1000的服务定义,其专属元数据应当位于:
/etc/cas/config/saml/metadata/SampleService-1000从源码印证:FileSystemSamlIdPMetadataLocator#getMetadataArtifact 的解析顺序是——当请求携带registeredService时,先尝试<元数据目录>/<按服务目录名>/<产物文件名>;只有当该服务目录或对应产物不存在时,才回退到全局的<元数据目录>/<产物文件名>。因此service参数的实际效果是切换产物查找位置,实现“同一端点、不同服务、不同元数据/证书”的覆盖。
通过 idpMetadataLocation 直接指定 SP 侧的 IdP 元数据位置
另一种方式是直接让 SAML2 服务提供者(SP)从磁盘指定位置定位 IdP 元数据。这在需要轮换 SAML2 IdP 元数据的签名/加密密钥、并希望让 SP 逐步(gradually)获取到新元数据的场景中非常有用:
{ "@class" : "org.apereo.cas.services.SamlRegisteredService", "serviceId" : "the-entity-id-of-the-sp", "name" : "SAMLService", "id" : 1, "metadataLocation" : "https://url/to/metadata.xml", "idpMetadataLocation" : "file:/path/to/idp/metadata/directory" }metadataLocation:SP 自身元数据的 URL(SP 元数据地址);idpMetadataLocation:指示该 SP 从磁盘目录读取IdP元数据的开关/定位字段。
源码中同样可以印证这一字段的作用:在 FileSystemSamlIdPMetadataLocator 的getMetadataArtifact中,若注册服务的getIdpMetadataLocation()非空,会优先以该属性解析出的目录作为服务专属产物目录(支持 SpEL 表达式解析),而不再使用默认目录下的<服务名>-<id>子目录。测试 SamlIdPMetadataResolverTests 验证了带/不带服务上下文时元数据解析器的解析行为。
典型的密钥轮换工作流即:把新的idp-signing.crt/idp-signing.key、idp-encryption.crt/idp-encryption.key与更新后的idp-metadata.xml写入idpMetadataLocation指向的独立目录,让个别 SP 先行切换到新元数据,再逐步推广。
四、高级策略:其他元数据管理后端一览
除了文件系统,SP 或 IdP 元数据还可以使用以下任意一种策略来管理(每种策略有独立的配置前缀与专属文档,均以cas.authn.saml-idp.metadata.*为根前缀,对应的配置模型字段在 SamlIdPMetadataProperties.java 中声明):
| 存储后端 | 说明文档(仓库相对路径) |
|---|---|
| Metadata Query Protocol | MDQ 指南 |
| HTTP/HTTPS | HTTP 指南 |
| REST | REST 指南 |
| Git | Git 指南 |
| MongoDb | MongoDb 指南 |
| Redis | Redis 指南 |
| JPA | JPA 指南 |
| Groovy | Groovy 指南 |
| Amazon S3 | Amazon S3 指南 |
| DynamoDb | DynamoDb 指南 |
| Google Cloud Storage | GCP Storage 指南 |
这些后端对应的实现分别位于cas-server-support-saml-idp-metadata-*、cas-server-support-saml-idp等模块中,选型时可根据部署环境(本地文件系统、数据库、对象存储、协议级 MDQ)决定。
五、与 SAML 服务管理的关系
配置元数据端点只是 IdP 侧工作的一半,另一半是正确注册和管理 SAML2 服务提供者。SP 的注册、属性释放策略等配置请参阅 SAML2 服务管理指南。
六、小结与可验证要点
- 三个端点
/idp/metadata、/idp/metadata/signingCertificate、/idp/metadata/encryptionCertificate均为 GET 访问;元数据缺失时自动触发生成(SamlIdPMetadataController.java)。 service参数支持实体 id 与数字 id 两种形式,用于按服务注册表匹配并合并 IdP 元数据覆盖项。- 文件系统默认产物为 5 个具名文件:
idp-metadata.xml、idp-signing.crt/key、idp-encryption.crt/key,目录由cas.authn.saml-idp.metadata.file-system.location控制(默认file:/etc/cas/saml)。 - 按服务覆盖的两种途径:
<元数据目录>/<服务名>-<服务id>子目录,或在服务定义中设置idpMetadataLocation指向独立磁盘目录(适用于密钥轮换的灰度切换)。 sign-metadata控制是否用 IdP 签名证书对落盘元数据做数字签名;密钥长度与证书算法由core.key-size(默认 4096)与core.certificate-algorithm(默认SHA512withRSA)决定。- 磁盘产物可用 CAS 配置安全机制加密,参见 CAS 配置安全。
- 后端
- 认证鉴权
- 单点登录
【免费下载链接】cas
Apereo CAS - Identity & Single Sign On for all earthlings and beyond.
相关推荐
Apereo CAS SAML2 元数据的 Redis 管理:动态元数据存储、按服务覆盖与实现解析
Apereo CAS SAML2 元数据的 Redis 管理:动态元数据存储、按服务覆盖与实现解析 在 Apereo CAS 中充当 SAML2 身份提供者(I
后端认证鉴权单点登录Apereo CAS 中使用 Google Cloud Storage 托管 SAML2 IdP 元数据:JSON 文档结构、GCS 对象布局与每服务覆盖机制
Apereo CAS 中使用 Google Cloud Storage 托管 SAML2 IdP 元数据:JSON 文档结构、GCS 对象布局与每服务覆盖机制
后端认证鉴权单点登录Apereo CAS:使用 MongoDb 实现 SAML2 元数据的集中式管理与 IdP 元数据动态存储
Apereo CAS:使用 MongoDb 实现 SAML2 元数据的集中式管理与 IdP 元数据动态存储 本篇技术指南基于 Apereo CAS 官方文档 C
后端认证鉴权单点登录
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考