- 后端
- 认证鉴权
- 单点登录
【免费下载链接】cas
Apereo CAS - Identity & Single Sign On for all earthlings and beyond.
导读
本指南围绕 Apereo CAS 官方文档 Configuration-Server-Management-SpringCloud-GCP-SecretManager.md 展开,讲解如何借助 Spring Cloud GCP 将 Google Cloud Secret Manager 作为 CAS 的外部配置数据源,把敏感属性与密钥从应用包中剥离出来集中托管。读完本文,你将掌握模块引入方式、五种sm@地址语法、CAS 配置中的实际用法,以及该能力在仓库源码中的自动装配实现与测试验证路径。
功能定位与适用场景
CAS 的配置管理支持多种策略:默认的 Standalone 策略 由 CAS 自身承载配置,而 Spring Cloud 策略则把配置外部化到独立的配置服务器中。当配置需要跟随云环境动态变化、且涉及大量敏感凭据(数据库口令、第三方 API Key、认证源密码等)时,把这类属性放入 Google Cloud Secret Manager 是一种常见的云原生实践。
CAS 通过 Spring Cloud GCP 项目接入 Google Cloud Secret Manager,从而能够在运行时定位并加载属性与设置。该功能的定位不仅是"配置服务器的一个数据源"——正如 Configuration-Server-Management-SpringCloud.md 中列举的众多 Spring Cloud 配置来源(Amazon S3、Amazon Secret Manager、Azure KeyVault、DynamoDb、Etcd、HashiCorp Vault、JDBC、MongoDb、ZooKeeper 等)一样,GCP Secret Manager 是其中可选的数据源之一,实现上完全复用 Spring Cloud Config 的外部化配置机制。
引入依赖:WAR Overlay 中的模块声明
在 CAS WAR Overlay 中,通过声明以下模块即可启用该能力:
implementation "org.apereo.cas:cas-server-support-configuration-cloud-gcp-secretsmanager"对应模块在仓库中的工程定义为 support/cas-server-support-configuration-cloud-gcp-secretsmanager/build.gradle,其模块描述为:"Loads CAS configuration from Google Cloud Secret Manager so settings can be managed outside the application package"(从 Google Cloud Secret Manager 加载 CAS 配置,使设置可在应用包之外管理)。该模块在 settings.gradle 中以include "support:cas-server-support-configuration-cloud-gcp-secretsmanager"被纳入多模块构建,其第三方依赖spring-cloud-gcp-secretmanager(对应com.google.cloud:spring-cloud-gcp-secretmanager)在 gradle/libs.versions.toml 中统一版本管理。
注意:
cas-server-support-configuration-cloud-gcp-secretsmanager是仓库当前实际使用的模块名(对应spring.cloud.gcp.secretmanager系列属性),与 AWS 侧使用的cas-server-support-configuration-cloud-aws-secretsmanager相呼应。请以模块实际发布名为准进行依赖声明。
两种部署形态:配置服务器与 Overlay 直连
官方文档明确指出:本模块并不专属属于 Spring Cloud 配置服务器,它同样可以原样用在 CAS Server Overlay 内部。这意味着存在两种典型用法:
- Spring Cloud 配置服务器内部:作为配置服务器的数据源之一,集中拉取各环境的外部化设置;
- CAS Server Overlay 直连:CAS 以独立(Standalone)模式运行时,直接从 Secret Manager 获取设置,无需单独部署配置服务器。
在第二种形态下,所有来源的配置(无论格式与语法)会并列协作共同提供设置,你可以按需混用多种来源。这也与 Configuration-Server-Management-SpringCloud.md 中"复合来源(Composite Sources)"的说明一致:在配置服务器的application.properties或 YAML 中启用多个 profile,即可从多个环境仓库同时拉取配置。
Secret Manager 配置数据资源的工作原理
该功能基于 Spring Boot 的Config Data API实现:Secret Manager 被当作一个"外部配置数据资源"(Config Data Resource),CAS 可以从中把指定的密钥(Secret)以属性的形式装载进应用上下文。
从源码看,核心装配类为 CasGoogleCloudSecretsManagerCloudConfigBootstrapAutoConfiguration.java。它位于org.apereo.cas.config包,自 CAS 7.0.0 起提供,关键特征如下:
- 通过
@ConditionalOnFeatureEnabled(feature = CasFeatureModule.FeatureCatalog.CasConfiguration, module = "gcp-secretsmanager")与功能开关绑定,仅在该模块被启用时生效; - 通过
@ConditionalOnProperty(value = "spring.cloud.gcp.secretmanager.enabled", matchIfMissing = true)控制,即默认开启; @AutoConfiguration(after = GcpSecretManagerAutoConfiguration.class)确保在 Spring Cloud GCP 的自动配置之后执行;- 装配了三个核心 Bean:
googleCloudSecretsManagerPropertySourceLocator:一个PropertySourceLocator,负责把 Secret Manager 内容定位为环境中的PropertySource;googleCloudSecretsManagerTemplate:基于SecretManagerServiceClient构建的SecretManagerTemplate,并设置UserAgentHeaderProvider;googleCloudSecretsManagerCredentialProvider:基于DefaultCredentialsProvider构造的CredentialsProvider。
当PropertySourceLocator被调用时,代码会解析出项目 ID 提供者(GcpProjectIdProvider),并最终构造SecretManagerPropertySource。这正是"以sm@语法在属性占位符中读取密钥"得以工作的底层链路。
sm@地址语法:五种形式详解
Secret Manager 配置数据资源使用如下语法指定要读取的密钥。这是官方文档的核心内容,务必完整掌握:
# 1. 长形式 - 指定 project ID、secret ID 与版本号 sm@projects/<project-id>/secrets/<secret-id>/versions/<version-id> # 2. 长形式 - 指定 project ID、secret ID,使用最新版本 sm@projects/<project-id>/secrets/<secret-id> # 3. 短形式 - 指定 project ID、secret ID 与版本号 sm@<project-id>/<secret-id>/<version-id> # 4. 短形式 - 使用默认项目;指定 secret + version # # 项目从 spring.cloud.gcp.secretmanager.project-id 设置中推断 # (配置在 bootstrap.properties 中),若未设置则从 # application-default credentials(应用默认凭据)推断。 sm@<secret-id>/<version> # 5. 最短形式 - 仅指定 secret ID,使用默认项目与最新版本 sm@<secret-id>五种形式可归纳为三条规则:
- 长形式(1、2):显式携带
projects/<project-id>/secrets/<secret-id>路径结构,最清晰、最不易产生歧义;形式 2 省略/versions/<version-id>时自动取最新版本; - 短形式(3):以
project-id/secret-id/version-id三段式紧凑表达,适用于需要在地址里显式指定版本的场景; - 省略形式(4、5):依赖
spring.cloud.gcp.secretmanager.project-id(配置于bootstrap.properties)或应用默认凭据(ADC,Application Default Credentials)推断项目,版本号同样可省略以取最新版本。
在 CAS 配置中使用:实战示例
官方文档给出了在 CAS 配置中直接使用该语法的示例:
# 可选配置项,用于显式声明导入 # spring.config.import=sm@ # 长形式示例:读取 projects/<project-id>/secrets/cas_some_property 中的值 cas.some.property=${sm@projects/<project-id>/secrets/cas_some_property}要点说明:
spring.config.import=sm@是可选配置:注释掉它也可以工作,因为 CAS 的PropertySourceLocator会在引导阶段主动把 Secret Manager 挂载为配置源;- 属性占位符
${sm@...}中的地址会被解析为密钥的实际值,因此cas.some.property最终拿到的是 Secret Manager 中存储的明文内容; - 结合前文的省略形式,还可以写作
${sm@cas_some_property}(默认项目 + 最新版本),或${sm@<project-id>/cas_some_property/3}(指定版本)等变体。
仓库测试 GoogleCloudSecretsManagerCloudConfigBootstrapConfigurationTests.java 验证了这一行为:测试通过source.getProperty("sm@projects/1234567890/secrets/cas_authn_accept_users")读取密钥,断言其值等于预先写入的casuser::Hello(真实连接本地 9090 端口的 Secret Manager 模拟服务时)或casuser::Mellon(使用 Mockito 模拟客户端时)。测试中实际创建的密钥包括cas_authn_accept_users与cas_authn_accept_enabled,前者对应 CAS 的cas.authn.accept.users配置语义,可见该机制完全可用于承载如"静态认证用户清单"这类既有敏感属性、也有业务语义的配置项。
关键配置项:项目 ID、开关与默认值
结合源码与测试,围绕该模块的关键配置项如下:
| 配置项 | 作用 | 说明 |
|---|---|---|
spring.cloud.gcp.secretmanager.enabled | 是否启用 Secret Manager 配置源 | 源码中matchIfMissing = true,即默认启用;测试中显式设为true |
spring.cloud.gcp.secretmanager.project-id | 指定 GCP 项目 ID | 用于省略形式的地址推断;若未设置,回退到DefaultGcpProjectIdProvider(即应用默认凭据/环境推断) |
spring.cloud.gcp.secretmanager.allow-default-secret | 是否允许默认密钥值兜底 | 源码中通过secretManagerTemplate.setAllowDefaultSecretValue(properties.isAllowDefaultSecret())透传给模板,控制当目标密钥不存在时的行为 |
在 BaseGoogleCloudSecretsManagerTests.java 中可以看到典型测试装配:
spring.cloud.gcp.secretmanager.enabled=true spring.cloud.gcp.secretmanager.project-id=project-12345同时测试通过自定义CredentialsProviderBean(NoCredentialsProvider)注入无凭据客户端,这说明了另一个重要事实:凭据注入点是可替换的——CAS 默认使用DefaultCredentialsProvider走 ADC 链路,但部署方也可以自行覆盖googleCloudSecretsManagerCredentialProviderBean。
凭据解析与项目 ID 回退逻辑
源码中getProjectIdProvider的判定逻辑非常清晰,可以直接作为排查依据:
private static GcpProjectIdProvider getProjectIdProvider(final GcpSecretManagerProperties properties) { return StringUtils.isNotBlank(properties.getProjectId()) ? properties::getProjectId : new DefaultGcpProjectIdProvider(); }即:只要显式配置了spring.cloud.gcp.secretmanager.project-id,就优先使用它;否则交由DefaultGcpProjectIdProvider(来自 Spring Cloud GCP Core)根据运行环境(如 GCE 元数据、GOOGLE_CLOUD_PROJECT 环境变量、ADC 凭据文件等)推断项目。这一逻辑与文档中"项目从bootstrap.properties的spring.cloud.gcp.secretmanager.project-id推断,未设置则用 application-default credentials"的描述完全吻合。
运行时配置更新与生态协同
虽然本文聚焦 GCP Secret Manager,但需要说明:Secret Manager 这类外部配置源在 CAS 中属于"外部化配置"的一部分,CAS 还提供了配置热更新的能力(详见 Configuration-Management-Reload.md),并与 Configuration-Management.md 中描述的configProps, env, beans, conditions等 Actuator 端点协同,便于运维人员观察配置装载结果。在多节点分布式部署时,可结合 Spring Cloud Bus 将配置变更广播到各 CAS 节点。
常见问题与排查建议
- 属性解析为空或启动失败:优先检查
spring.cloud.gcp.secretmanager.project-id是否与密钥所在项目一致;使用省略形式时,项目依赖配置或 ADC 推断,环境差异最容易导致"读不到值"。 - 凭据异常(401/403):确认运行环境已配置 ADC(如
GOOGLE_APPLICATION_CREDENTIALS指向服务账号 JSON),或已覆盖googleCloudSecretsManagerCredentialProviderBean 注入自定义凭据。 - 地址语法拼写:
sm@前缀必须保留;长形式中的projects/、secrets/、versions/段路径不可随意增删。版本号可省略(取最新),但项目、密钥两个要素至少要有(见五种形式规则)。 - 版本管理:若希望密钥轮换时配置不受影响,应固定版本号(形式 1 或 3);若希望始终跟随最新值,则省略版本段。
小结
通过cas-server-support-configuration-cloud-gcp-secretsmanager模块,CAS 得以在 Spring Cloud 配置体系内直接消费 Google Cloud Secret Manager 的密钥。五种sm@地址语法覆盖了从"全量显式"到"最简省略"的表达粒度;PropertySourceLocator+SecretManagerTemplate的装配链路(见 CasGoogleCloudSecretsManagerCloudConfigBootstrapAutoConfiguration.java)则保证了该能力可同时服务于 Spring Cloud 配置服务器与 CAS Overlay 直连两种形态。结合测试用例与实际配置示例,你可以快速将敏感属性从应用包中剥离,实现云原生的密钥托管与动态加载。
- 后端
- 认证鉴权
- 单点登录
【免费下载链接】cas
Apereo CAS - Identity & Single Sign On for all earthlings and beyond.
相关推荐
WinUtil 保姆级上手指南:如何一键搞定 90% 的 Windows 装机、优化与修复
WinUtil 保姆级上手指南:如何一键搞定 90% 的 Windows 装机、优化与修复 WinUtil 是一款开源的 Windows 一体化工具箱(官方名称
后端认证鉴权单点登录Ory Hydra与Google Cloud Secret Manager轮换集成:配置
Ory Hydra与Google Cloud Secret Manager轮换集成:配置 概述 在现代云原生应用中,密钥管理是确保系统安全的关键环节。Ory H
认证鉴权后端Ryujinx:在PC上免费畅玩Switch游戏的终极完整指南
Ryujinx:在PC上免费畅玩Switch游戏的终极完整指南 想要在电脑上体验任天堂Switch游戏的魅力吗?Ryujinx Switch模拟器为你提供了完美
后端认证鉴权单点登录
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考