Spring CredHub指南

2023/05/11

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. 为什么凭证管理很重要?

凭证管理是对凭证整个生命周期进行安全、集中处理的过程,主要包括生成、创建、轮换和撤销。尽管每家公司的应用程序和信息技术环境彼此截然不同,但有一点是一致的:凭证,每个应用程序都需要凭证才能访问其他应用程序、数据库或工具。

凭据管理对于数据安全至关重要,因为它允许用户和应用程序访问敏感信息。因此,确保它们在运输途中和静止时的安全非常重要。最好的策略之一是用API调用CredHub等专用凭证管理工具来以编程方式检索凭证,从而取代硬编码凭证及其手动管理。

4. CredHub API

4.1 验证

有两种验证CredHub API的方法:UAA(OAuth2)和双向TLS

默认情况下,CredHub提供集成的双向TLS身份验证。要使用此方案,请在应用程序属性中指定CredHub服务器的URL:

spring:
    credhub:
        url: <CredHub URL>

验证API的另一种方法是通过UAA,它需要客户端凭据授予令牌才能获取访问令牌:

spring:
    credhub:
        url: <CredHub URL>
        oauth2:
            registration-id: <credhub-client>
    security:
        oauth2:
            client:
                registration:
                    credhub-client:
                        provider: uaa
                        client-id: <OAuth2 client ID>
                        client-secret: <OAuth2 client secret>
                        authorization-grant-type: <client_credentials>
                provider:
                    uaa:
                        token-uri: <UAA token server endpoint>

然后可以将访问令牌传递给授权标头。

4.2 Credentials API

通过CredHubCredentialOperations接口,我们可以调用CredHub API来创建、更新、检索和删除凭据。CredHub支持的凭证类型有:

  • value:单个配置的字符串
  • json:用于静态配置的JSON对象
  • user:3个字符串–用户名、密码和密码哈希
  • password:用于密码和其他字符串凭据的字符串
  • certificate:包含根CA、证书和私钥的对象
  • rsa:包含公钥和私钥的对象
  • ssh:包含SSH格式公钥和私钥的对象

4.2 Permissions API

写入凭证时会提供权限,以控制用户可以访问、更新或检索的内容。Spring CredHub提供了CredHubPermissionV2Operations接口来创建、更新、检索和删除权限。允许用户对凭据执行的操作是:读取、写入和删除。

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、用于rsa凭证的RsaCredentialRequest等:

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 凭证轮换和撤销

凭证管理的另一个重要阶段是轮换凭证。下面的代码演示了我们如何使用密码凭证类型实现这一点:

CredentialDetails<PasswordCredential> newPassword = credentialOperations.regenerate(credentialName, PasswordCredential.class);

CredHub还允许证书凭据类型同时具有多个活动版本,以便它们可以在不停机的情况下轮换。凭证管理的最后也是最关键的阶段是撤销凭证,可以按如下方式实现:

credentialOperations.deleteByName(credentialName);

5.5 凭证检索

现在我们已经了解了完整的凭证管理生命周期。我们将了解如何检索用于Orders API身份验证的最新版本的密码凭证:

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 控制对凭据的访问

可以将权限附加到凭证以限制访问。例如,授予单个用户访问凭据并使该用户能够对凭据执行所有操作的权限。可以附加另一个权限,允许所有用户仅对凭证执行READ操作。

让我们看一个向凭证添加权限以允许用户u101执行READ和WRITE操作的示例:

Permission permission = Permission.builder()
    .app(UUID.randomUUID().toString())
    .operations(Operation.READ, Operation.WRITE)
    .user("u101")
    .build();
permissionOperations.addPermissions(name, permission);

除了READ和WRITE之外,Spring CredHub还提供对其他几种操作的支持,这允许用户:

  • READ:通过id和name获取凭证
  • WRITE:按名称设置、生成和重新生成凭证
  • DELETE:按名称删除凭证
  • READ_ACL:通过凭据名称获取ACL(访问控制列表)
  • WRITE_ACL:添加和删除凭证ACL的条目

6. 总结

在本教程中,我们展示了如何使用Spring CredHub库将CredHub与Spring Boot集成。我们集中管理订单应用程序的凭据,涵盖两个关键方面:凭据生命周期和权限

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章