© 2017-2021 原作者。

本文档的副本可以供您自己使用和分发给其他人,前提是您不对此类副本收取任何费用,并且进一步前提是每份副本都包含本版权声明,无论是印刷版还是电子版。

Spring CredHub 为在Cloud Foundry平台中运行的CredHub服务器存储、检索和删除凭据提供客户端支持。

CredHub 提供了一个HTTP API来安全地存储、生成、检索和删除各种类型的凭证。Spring CredHub 为 CredHub API 提供了 Java 绑定,使 Spring 应用程序与 CredHub 的集成变得容易。

1. 入门

Spring CredHub 支持 CredHub 服务器版本 1.x 和 2.x。该库旨在提供对 CredHub API 的全面覆盖——对所有凭证类型的所有操作。

Spring CredHub 已针对 Spring Boot 应用程序进行了优化。要在 Spring Boot 应用程序中包含 Spring CredHub,请将一些依赖项添加到项目构建文件中。

1.1。Maven 依赖项

将 Spring CredHub 启动器添加到dependencies构建文件的部分:

    <dependencies>
        <dependency>
            <groupId>org.springframework.credhub</groupId>
            <artifactId>spring-credhub-starter</artifactId>
            <version>2.2.0</version>
        </dependency>
    </dependencies>

要在 Spring CredHub 中启用响应式支持,请将以下Spring WebFlux依赖项添加到构建文件中:

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
            <version>5.3.13</version>
        </dependency>
    </dependencies>

要对 CredHub 使用 OAuth2 身份验证,请将以下Spring Security依赖项添加到构建文件中:

    <dependencies>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>5.5.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-oauth2-client</artifactId>
            <version>5.5.3</version>
        </dependency>
    </dependencies>

1.2. Gradle 依赖项

将 Spring CredHub 启动器添加到dependencies构建文件的部分:

    dependencies {
        compile('org.springframework.credhub:spring-credhub-starter:2.2.0')
    }

要在 Spring CredHub 中启用响应式支持,请将以下Spring WebFlux依赖项添加到构建文件中:

    dependencies {
        compile("org.springframework.boot:spring-boot-starter-webflux:5.3.13")
    }

要对 CredHub 使用 OAuth2 身份验证,请将以下Spring Security依赖项添加到构建文件中:

    dependencies {
        compile("org.springframework.security:spring-security-config:5.5.3")
        compile("org.springframework.security:spring-security-oauth2-client:5.5.3")
    }

2. Spring Boot 配置

使用 Spring CredHub 启动器依赖项时,可以使用Spring Boot 应用程序属性配置 Spring CredHub 。使用正确的配置属性,Spring CredHub 将自动配置与 CredHub 服务器的连接。

2.1。双向 TLS 身份验证

在 Cloud Foundry 上运行的应用程序可以使用双向 TLS 向部署到同一平台的 CredHub 服务器进行身份验证。当没有提供其他身份验证凭据时,相互 TLS 是默认身份验证方案。要对 CredHub 服务器使用双向 TLS 身份验证,只需提供 CredHub 服务器的 URL 作为应用程序属性:

spring:
  credhub:
    url: [CredHub server URL]

有关双向 TLS 身份验证的更多信息,请参阅CredHub 文档

在 Cloud Foundry 上运行的应用程序可以使用内部地址https://credhub.service.cf.internal:8844与部署到同一平台的 CredHub 服务器进行通信。

2.2. OAuth2 身份验证

OAuth2 可用于通过 UAA 对任何 CredHub 服务器进行身份验证。Spring CredHub 支持使用以下 Spring CredHub 和 Spring Security 配置的客户端凭据授予令牌进行身份验证:

spring:
  credhub:
    url: [CredHub server 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]

中提供的 IDspring.credhub.oauth2.registration-id必须引用在 下配置的客户端spring.security.oauth2.client.registration。有关 Spring Boot OAuth2 客户端配置的更多信息,请参阅Spring Boot 文档

在 Spring Security 客户端注册中指定的 OAuth2 客户端必须具有 CredHub 范围,例如credhub.readorcredhub.write才能执行大多数操作。有关使用 UAA 进行 OAuth2 身份验证的更多信息,请参阅CredHub 文档

2.2.1。Spring Security OAuth2 的自动配置

spring.credhub.oauth2设置属性并且 Spring Security 在应用程序类路径上时,Spring CredHub 将自动配置 OAuth2 身份验证所需的 Spring Security bean。如果需要,应用程序可以提供所需的 Spring Security OAuth2 bean 来覆盖自动配置。

Servlet 和非反应式应用程序

Spring CredHub 需要 Spring Security 提供的以下类型的 bean,以便使用 OAuth2 进行身份验证。

所需的 Bean 类型 自动配置类型

ClientRegistrationRepository

InMemoryClientRegistrationRepository

OAuth2AuthorizedClientRepository

AuthenticatedPrincipalOAuth2AuthorizedClientRepository

OAuth2AuthorizedClientManager

DefaultOAuth2AuthorizedClientManager

自动配置DefaultOAuth2AuthorizedClientManager假定应用程序在 servlet 容器中运行并且具有活动的HttpServletRequest. 应用程序可能需要提供OAuth2AuthorizedClientManagerbean 的替代实现,例如AuthorizedClientServiceOAuth2AuthorizedClientManager处理 之外的请求HttpServletRequest,如以下示例所示:

/*
 * Copyright 2016-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.credhub;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.client.AuthorizedClientServiceOAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.ClientCredentialsOAuth2AuthorizedClientProvider;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;

@Configuration
public class CredHubSecurityConfiguration {

	@Bean
	public AuthorizedClientServiceOAuth2AuthorizedClientManager reactiveClientManager(
			ClientRegistrationRepository clientRegistrationRepository,
			OAuth2AuthorizedClientService authorizedClientService) {
		AuthorizedClientServiceOAuth2AuthorizedClientManager clientManager = new AuthorizedClientServiceOAuth2AuthorizedClientManager(
				clientRegistrationRepository, authorizedClientService);
		clientManager.setAuthorizedClientProvider(new ClientCredentialsOAuth2AuthorizedClientProvider());
		return clientManager;
	}

}

有关配置其他 bean 的更多信息和示例,请参阅Spring Security 文档

反应式应用程序

Spring CredHub 需要 Spring Security 提供的以下类型的 bean,以便使用 OAuth2 进行身份验证。

所需的 Bean 类型 自动配置类型

ReactiveClientRegistrationRepository

InMemoryReactiveClientRegistrationRepository

ServerOAuth2AuthorizedClientRepository

UnAuthenticatedServerOAuth2AuthorizedClientRepository

ReactiveOAuth2AuthorizedClientManager

DefaultReactiveOAuth2AuthorizedClientManager

自动配置DefaultReactiveOAuth2AuthorizedClientManager需要一个活动ServerHttpRequest上下文。应用程序可能需要提供ReactiveOAuth2AuthorizedClientManagerbean 的替代实现,例如AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager处理 之外的请求ServerHttpRequest,如以下示例所示:

/*
 * Copyright 2016-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.credhub;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.client.AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.ClientCredentialsReactiveOAuth2AuthorizedClientProvider;
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;

@Configuration
public class CredHubReactiveSecurityConfiguration {

	@Bean
	public AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager reactiveClientManager(
			ReactiveClientRegistrationRepository clientRegistrationRepository,
			ReactiveOAuth2AuthorizedClientService authorizedClientService) {
		AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager clientManager = new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(
				clientRegistrationRepository, authorizedClientService);
		clientManager.setAuthorizedClientProvider(new ClientCredentialsReactiveOAuth2AuthorizedClientProvider());
		return clientManager;
	}

}

有关配置其他 bean 的更多信息和示例,请参阅Spring Security 文档

3. CredHubOperations 简介

接口org.springframework.credhub.core.CredHubOperations和实现org.springframework.credhub.core.CredHubTemplate是 Spring CredHub 中的中心类。 CredHubOperations提供对模拟完整 CredHub API 的其他操作接口的访问:

/**
 * Get the operations for saving, retrieving, and deleting credentials.
 */
CredHubCredentialOperations credentials();

/**
 * Get the operations for adding, retrieving, and deleting credential permissions.
 */
CredHubPermissionOperations permissions();

/**
 * Get the operations for adding, retrieving, and deleting credential permissions.
 */
CredHubPermissionV2Operations permissionsV2();

/**
 * Get the operations for retrieving, regenerating, and updating certificates.
 */
CredHubCertificateOperations certificates();

/**
 * Get the operations for interpolating service binding credentials.
 */
CredHubInterpolationOperations interpolation();

/**
 * Get the operations for retrieving CredHub server information.
 */
CredHubInfoOperations info();

3.1。映射到 CredHub API

接口的每个方法都Operations直接映射到 CredHub HTTP API 的一个端点。下表显示了 CredHub API 和相应的 Spring CredHubOperations接口之间的映射。

CredHub 凭证 API

CredHubCredentialOperations

CredHub 权限 API (v1)

CredHubPermissionOperations

CredHub 权限 API (v2)

CredHubPermissionV2 操作

CredHub 证书 API

CredHubCertificateOperations

CredHub 插值 API

CredHubInterpolationOperations

CredHub 信息接口

CredHubInfo 操作

3.2. CredHubOperations 自动配置

正确配置应用程序属性时,使用CredHubOperationsSpring Boot 自动配置创建 Spring bean。应用程序类可以自动装配此 bean 的实例以与 CredHub 服务器交互。

/*
 * Copyright 2016-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.credhub;

import org.springframework.credhub.core.CredHubOperations;
import org.springframework.credhub.support.CredentialDetails;
import org.springframework.credhub.support.SimpleCredentialName;
import org.springframework.credhub.support.password.PasswordCredential;
import org.springframework.credhub.support.password.PasswordParameters;
import org.springframework.credhub.support.password.PasswordParametersRequest;
import org.springframework.stereotype.Component;

@Component
public class CredHubService {

	private final CredHubOperations credHubOperations;

	private final SimpleCredentialName credentialName;

	public CredHubService(CredHubOperations credHubOperations) {
		this.credHubOperations = credHubOperations;

		this.credentialName = new SimpleCredentialName("example", "password");
	}

	public String generatePassword() {
		PasswordParameters parameters = PasswordParameters.builder().length(12).excludeLower(false).excludeUpper(false)
				.excludeNumber(false).includeSpecial(true).build();

		CredentialDetails<PasswordCredential> password = this.credHubOperations.credentials()
				.generate(PasswordParametersRequest.builder().name(this.credentialName).parameters(parameters).build());

		return password.getValue().getPassword();
	}

	public String getPassword() {
		CredentialDetails<PasswordCredential> password = this.credHubOperations.credentials()
				.getByName(this.credentialName, PasswordCredential.class);

		return password.getValue().getPassword();
	}

}

4. ReactiveCredHubOperations介绍

接口org.springframework.credhub.core.ReactiveCredHubOperations和实现org.springframework.credhub.core.ReactiveCredHubTemplate是 Spring CredHub 响应式支持中的中心类。 ReactiveCredHubOperations提供对模拟完整 CredHub API 的其他操作接口的访问:

/**
 * Get the operations for saving, retrieving, and deleting credentials.
 */
ReactiveCredHubCredentialOperations credentials();

/**
 * Get the operations for adding, retrieving, and deleting credential permissions.
 */
ReactiveCredHubPermissionOperations permissions();

/**
 * Get the operations for adding, retrieving, and deleting credential permissions.
 */
ReactiveCredHubPermissionV2Operations permissionsV2();

/**
 * Get the operations for retrieving, regenerating, and updating certificates.
 */
ReactiveCredHubCertificateOperations certificates();

/**
 * Get the operations for interpolating service binding credentials.
 */
ReactiveCredHubInterpolationOperations interpolation();

/**
 * Get the operations for retrieving CredHub server information.
 */
ReactiveCredHubInfoOperations info();

4.2. ReactiveCredHubOperations 自动配置

ReactiveCredHubOperations正确配置应用程序属性并且 Spring WebFlux 库位于类路径上时,使用 Spring Boot 自动配置创建 Spring bean。应用程序类可以自动装配此 bean 的实例以与 CredHub 服务器交互。

/*
 * Copyright 2016-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.credhub;

import reactor.core.publisher.Mono;

import org.springframework.credhub.core.ReactiveCredHubOperations;
import org.springframework.credhub.support.SimpleCredentialName;
import org.springframework.credhub.support.password.PasswordCredential;
import org.springframework.credhub.support.password.PasswordParameters;
import org.springframework.credhub.support.password.PasswordParametersRequest;
import org.springframework.stereotype.Component;

@Component
public class ReactiveCredHubService {

	private final ReactiveCredHubOperations credHubOperations;

	private final SimpleCredentialName credentialName;

	public ReactiveCredHubService(ReactiveCredHubOperations credHubOperations) {
		this.credHubOperations = credHubOperations;

		this.credentialName = new SimpleCredentialName("example", "password");
	}

	public Mono<String> generatePassword() {
		PasswordParameters parameters = PasswordParameters.builder().length(12).excludeLower(false).excludeUpper(false)
				.excludeNumber(false).includeSpecial(true).build();

		return this.credHubOperations.credentials()
				.generate(PasswordParametersRequest.builder().name(this.credentialName).parameters(parameters).build(),
						PasswordCredential.class)
				.map((password) -> password.getValue().getPassword());
	}

	public Mono<String> getPassword() {
		return this.credHubOperations.credentials().getByName(this.credentialName, PasswordCredential.class)
				.map((password) -> password.getValue().getPassword());
	}

}

5. HTTP 客户端支持

Spring CredHubCredHubOperations支持多个 HTTP 客户端库与 CredHub API 进行通信。支持以下库:

选择特定的客户端库需要在应用程序类路径上提供适当的依赖项。将按照上面列出的顺序检查每个客户端库的应用程序类路径。

Spring CredHubReactiveCredHubOperations仅支持 Netty HTTP 客户端库。

5.1。Apache HttpComponents

要使用 Apache HttpComponents 与 CredHub 通信,请将以下依赖项添加到应用程序:

<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpclient</artifactId>
</dependency>
可以通过日志配置启用 Apache HttpClient 的有线日志记录。确保不要意外启用线路日志记录,因为日志可能会以纯文本形式公开您的应用程序和 CredHub 之间的流量(包括令牌和机密)。

5.2. OkHttp 3

要使用 OkHttp 3 与 CredHub 通信,请将以下依赖项添加到应用程序:

<dependency>
  <groupId>com.squareup.okhttp3</groupId>
  <artifactId>okhttp</artifactId>
</dependency>

5.3. 网状

要使用 Netty 与 CredHub 通信,请在应用程序中添加以下依赖项:

<dependency>
  <groupId>io.netty</groupId>
  <artifactId>netty-all</artifactId>
</dependency>

1. see XML Configuration