1. 概述
本教程将实现 Spring CredHub,这是 CredHub 的 Spring 抽象层,用于存储带有访问控制规则的密钥,将凭证资源映射到用户和操作。⚠️ 注意:运行代码前需确保应用运行在已安装 CredHub 的 Cloud Foundry 平台上。
2. Maven 依赖
首先添加 spring-credhub-starter
依赖:
<dependency>
<groupId>org.springframework.credhub</groupId>
<artifactId>spring-credhub-starter</artifactId>
<version>2.2.0</version>
</dependency>
3. 为什么凭证管理很重要?
凭证管理是安全、集中处理凭证全生命周期的过程,主要包括生成、创建、轮换和撤销。尽管各公司的应用和 IT 环境差异很大,但有一件事是共通的:每个应用都需要凭证来访问其他应用、数据库或工具。
凭证管理对数据安全至关重要,它为用户和应用提供敏感信息访问权限。因此,确保凭证在传输和静态存储时的安全性非常重要。最佳实践之一是:用 API 调用替代硬编码凭证和手动管理,通过 CredHub 等专用工具程序化获取凭证。
4. CredHub API
4.1. 认证
CredHub API 支持两种认证方式:UAA(OAuth2) 和 双向 TLS
默认使用双向 TLS 认证,在应用配置中指定 CredHub 服务器 URL:
spring:
credhub:
url: https://credhub.example.com
另一种方式是通过 UAA 认证,需要客户端凭据获取访问令牌:
spring:
credhub:
url: https://credhub.example.com
oauth2:
registration-id: credhub-client
security:
oauth2:
client:
registration:
credhub-client:
provider: uaa
client-id: credhub-admin
client-secret: admin-secret
authorization-grant-type: client_credentials
provider:
uaa:
token-uri: https://uaa.example.com/oauth/token
访问令牌随后会被添加到授权头中。
4.2. 凭证 API
通过 CredHubCredentialOperations
接口,可调用 CredHub API 创建、更新、检索和删除凭证。CredHub 支持的凭证类型包括:
-
value
– 单个配置的字符串 -
json
– 静态配置的 JSON 对象 -
user
– 包含用户名、密码和密码哈希的 3 个字符串 -
password
– 密码和其他字符串凭证 -
certificate
– 包含根 CA、证书和私钥的对象 -
rsa
– 包含公钥和私钥的对象 -
ssh
– 包含 SSH 格式公钥和私钥的对象
4.3. 权限 API
权限在写入凭证时设置,用于控制用户访问、更新或检索的权限。Spring CredHub 提供 CredHubPermissionV2Operations
接口管理权限。用户允许的操作包括:read
、write
和 delete
。
5. CredHub 集成
我们将实现一个返回订单详情的 Spring Boot 应用,通过示例演示凭证管理的完整生命周期。
5.1. CredHubOperations
接口
CredHubOperations
接口位于 org.springframework.credhub.core
包中,是 Spring CredHub 的核心类,提供与 CredHub 交互的丰富功能。它访问建模整个 CredHub API 的接口,并在领域对象和 CredHub 数据间映射:
public class CredentialService {
private final CredHubCredentialOperations credentialOperations;
private final CredHubPermissionV2Operations permissionOperations;
public CredentialService(CredHubOperations credHubOperations) {
this.credentialOperations = credHubOperations.credentials();
this.permissionOperations = credHubOperations.permissionsV2();
}
}
5.2. 凭证创建
创建 password
类型凭证,使用 PasswordCredentialRequest
构建:
SimpleCredentialName credentialName = new SimpleCredentialName(credential.getName());
PasswordCredential passwordCredential = new PasswordCredential((String) value.get("password"));
PasswordCredentialRequest request = PasswordCredentialRequest.builder()
.name(credentialName)
.value(passwordCredential)
.build();
credentialOperations.write(request);
类似地,其他 CredentialRequest
实现可用于构建不同类型凭证,如 ValueCredentialRequest
(value
类型)、RsaCredentialRequest
(rsa
类型)等:
ValueCredential valueCredential = new ValueCredential((String) value.get("value"));
request = ValueCredentialRequest.builder()
.name(credentialName)
.value(valueCredential)
.build();
RsaCredential rsaCredential = new RsaCredential((String) value.get("public_key"), (String) value.get("private_key"));
request = RsaCredentialRequest.builder()
.name(credentialName)
.value(rsaCredential)
.build();
5.3. 凭证生成
Spring CredHub 支持动态生成凭证,避免应用端管理开销,提升数据安全性。实现方式如下:
SimpleCredentialName credentialName = new SimpleCredentialName("api_key");
PasswordParameters parameters = PasswordParameters.builder()
.length(24)
.excludeUpper(false)
.excludeLower(false)
.includeSpecial(true)
.excludeNumber(false)
.build();
CredentialDetails<PasswordCredential> generatedCred = credentialOperations.generate(PasswordParametersRequest.builder()
.name(credentialName)
.parameters(parameters)
.build());
String password = generatedCred.getValue().getPassword();
5.4. 凭证轮换与撤销
凭证轮换是管理的重要环节。以下代码演示 password
类型凭证的轮换:
CredentialDetails<PasswordCredential> newPassword = credentialOperations.regenerate(credentialName, PasswordCredential.class);
CredHub 允许 certificate
类型凭证同时存在多个活跃版本,实现零停机轮换。最关键的撤销阶段实现如下:
credentialOperations.deleteByName(credentialName);
5.5. 凭证检索
理解完整生命周期后,我们检索订单 API 认证所需的最新 password
凭证:
public ResponseEntity<Collection<Order>> getAllOrders() {
try {
String apiKey = credentialService.getPassword("api_key");
return new ResponseEntity<>(getOrderList(apiKey), HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.FORBIDDEN);
}
}
public String getPassword(String name) {
SimpleCredentialName credentialName = new SimpleCredentialName(name);
return credentialOperations.getByName(credentialName, PasswordCredential.class)
.getValue()
.getPassword();
}
5.6. 凭证访问控制
权限可附加到凭证以限制访问。例如:
- 权限 A:允许单个用户访问凭证并执行所有操作
- 权限 B:允许所有用户仅执行
READ
操作
添加权限示例(允许用户 u101
执行 READ
和 WRITE
):
Permission permission = Permission.builder()
.app(UUID.randomUUID().toString())
.operations(Operation.READ, Operation.WRITE)
.user("u101")
.build();
permissionOperations.addPermissions(name, permission);
Spring CredHub 支持的操作包括:
-
READ
– 按 ID/名称获取凭证 -
WRITE
– 按名称设置/生成/轮换凭证 -
DELETE
– 按名称删除凭证 -
READ_ACL
– 按凭证名称获取 ACL -
WRITE_ACL
– 添加/删除凭证 ACL 条目
6. 总结
本教程展示了如何使用 Spring CredHub 库集成 CredHub 与 Spring Boot。我们为订单应用集中管理凭证,覆盖两大关键点:凭证生命周期和权限控制。
完整源代码可在 GitHub 获取。