此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Vault 3.2.0! |
身份验证方法
不同的组织对安全有不同的要求 和身份验证。Vault 通过提供多重身份验证来反映这一需求 方法。Spring Vault 支持多种身份验证机制。
外部化登录凭据
首次访问安全系统称为安全引入。 任何客户端都需要临时或永久凭据才能访问 Vault。外部化凭据 是保持高代码可维护性的良好模式,但存在增加披露的风险。
向任何一方披露登录凭据允许登录 Vault 并访问 由基础角色允许。选择适当的客户端身份验证和 将凭据注入应用程序需要进行风险评估。
Spring 的 PropertySource 抽象是自然而然的 将配置保留在应用程序代码之外。您可以使用系统属性、环境 变量或属性文件来存储登录凭据。每种方法都有自己的属性。 请记住,命令行和环境属性可以使用适当的 作系统访问级别。
vault.token
到属性文件@PropertySource("configuration.properties")
@Configuration
public class Config extends AbstractVaultConfiguration {
@Override
public ClientAuthentication clientAuthentication() {
return new TokenAuthentication(getEnvironment().getProperty("vault.token"));
}
}
Spring 允许多种方式获取Environment .使用时VaultPropertySource ,注射通过@Autowired Environment environment 不会提供Environment 由于环境 Bean 仍在建设中,自动布线是在后期阶段进行的。您的配置类应该实现ApplicationContextAware 并获取Environment 从ApplicationContext . |
看SecurePropertyUsage.java
有关引用组件和其他属性源中的属性的示例。
Tokens认证
Tokens是 Vault 中身份验证的核心方法。 Tokens身份验证需要提供静态Tokens。
Tokens身份验证是默认的身份验证方法。 如果Tokens被披露为非预期方,则该Tokens将获得对 Vault 的访问权限,并且 可以访问目标客户端的密钥。 |
通常,Tokens身份验证用于创建和续订Tokens的方案
外部(例如 HashiCorp Vault 服务代理)。
根据实际设置,您可能希望也可能不需要Tokens续订和吊销。
看LifecycleAwareSessionManager
有关 TTL 和Tokens吊销的详细信息。
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
return new TokenAuthentication("…");
}
// …
}
另见:
AppRole 身份验证
AppRole 允许计算机 认证。AppRole 身份验证由两个难以猜测的(机密)组成 Tokens:RoleId 和 SecretId。
Spring Vault 通过仅提供 RoleId 来支持 AppRole 身份验证 或与提供的 SecretId 一起,并从 Vault 获取 RoleId/SecretId (推拉模式,响应展开)。
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
AppRoleAuthenticationOptions options = AppRoleAuthenticationOptions.builder()
.roleId(RoleId.provided("…"))
.secretId(SecretId.wrapped(VaultToken.of("…")))
.build();
return new AppRoleAuthentication(options, restOperations());
}
// …
}
Spring Vault 还支持全拉模式:如果未提供 RoleId 和 SecretId, Spring Vault 将使用角色名称和初始Tokens检索它们。这 初始Tokens可能与 TTL 和使用限制相关联。
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
VaultToken initialToken = VaultToken.of("…");
AppRoleAuthenticationOptions options = AppRoleAuthenticationOptions.builder()
.appRole("…")
.roleId(RoleId.pull(initialToken))
.secretId(SecretId.pull(initialToken))
.build();
return new AppRoleAuthentication(options, restOperations());
}
// …
}
AWS-EC2 身份验证
aws-ec2 auth 后端提供安全的引入机制 对于 AWS EC2 实例,允许自动检索 Vault Tokens。与大多数 Vault 身份验证后端不同,此后端 不需要首次部署或配置安全敏感型 凭据(Tokens、用户名/密码、客户端证书等)。 相反,它将 AWS 视为受信任的第三方,并使用 加密签名的动态元数据信息,唯一的 表示每个 EC2 实例。
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
return new AwsEc2Authentication(restOperations());
}
// …
}
AWS-EC2 身份验证默认情况下允许随机数遵循 首次使用时信任 (TOFU) 原则。任何意外的一方 获得对 PKCS#7 身份元数据的访问权限可以进行身份验证 反对 Vault。
在第一次登录期间,Spring Vault 会生成一个随机数 存储在实例 ID 旁边的身份验证后端中。 重新身份验证需要发送相同的随机数。任何其他 party 没有随机数,并且可以在 Vault 中针对 进一步调查。
随机数保存在内存中,并在应用程序重新启动期间丢失。
从 Spring Vault 3.2 开始,AWS-EC2 身份验证支持请求/响应 (IMDSv1) 元数据检索和基于会话的变体 (IMDSv2)。
AWS-EC2 身份验证角色是可选的,默认为 AMI。
您可以通过设置
它AwsEc2AuthenticationOptions
.
AWS-IAM 身份验证
aws auth 后端允许使用现有的 AWS IAM 凭证登录 Vault。
AWS IAM 身份验证会创建一个签名的 HTTP 请求,该请求是
由 Vault 执行,以使用 AWS STS 获取签名者的身份GetCallerIdentity
方法。AWSv4 签名需要 IAM 凭证。
可以从任一运行时环境中获取 IAM 凭证 或外部供应。运行时环境,例如 AWS-EC2、 分配了 IAM 主体的 Lambda 和 ECS 不需要特定于客户端 凭据的配置,但可以从其元数据源获取这些凭据。
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
AwsIamAuthenticationOptions options = AwsIamAuthenticationOptions.builder()
.credentials(new BasicAWSCredentials(…)).build();
return new AwsIamAuthentication(options, restOperations());
}
// …
}
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
AwsIamAuthenticationOptions options = AwsIamAuthenticationOptions.builder()
.credentialsProvider(InstanceProfileCredentialsProvider.getInstance()).build();
return new AwsIamAuthentication(options, restOperations());
}
// …
}
AwsIamAuthentication
需要 AWS Java SDK 依赖项 (com.amazonaws:aws-java-sdk-core
)
因为身份验证实施使用 AWS SDK 类型进行凭证和请求签名。
您可以通过以下方式配置身份验证AwsIamAuthenticationOptions
.
另见:
Azure (MSI) 身份验证
Azure 身份验证后端提供安全的引入机制 对于 Azure VM 实例,允许自动检索保管库 Tokens。与大多数 Vault 身份验证后端不同,此后端 不需要首次部署或配置安全敏感型 凭据(Tokens、用户名/密码、客户端证书等)。 相反,它将 Azure 视为受信任的第三方,并使用 托管服务标识和实例元数据信息,可以是 绑定到 VM 实例。
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
AzureMsiAuthenticationOptions options = AzureMsiAuthenticationOptions.builder()
.role(…).build();
return new AzureMsiAuthentication(options, restOperations());
}
// …
}
Azure 身份验证需要有关 VM 环境的详细信息(订阅 ID、
资源组名称、VM 名称)。这些详细信息可以通过AzureMsiAuthenticationOptionsBuilder
.
如果未配置,AzureMsiAuthentication
将 Azure 的实例元数据服务查询到
获取这些详细信息。
另见:
GCP-GCE 身份验证
gcp 身份验证后端允许使用现有的 GCP (Google Cloud Platform) IAM 和 GCE 凭据登录 Vault。
GCP GCE(Google Compute Engine)身份验证以 服务帐户的 JSON Web Tokens (JWT)。Compute Engine 实例的 JWT 是使用实例识别从 GCE 元数据服务获取的。 此 API 创建一个 JSON Web Tokens,可用于确认实例身份。
与大多数 Vault 身份验证后端不同,此后端 不需要首次部署或配置安全敏感型 凭据(Tokens、用户名/密码、客户端证书等)。 相反,它将 GCP 视为受信任的第三方,并使用 加密签名的动态元数据信息,唯一的 表示每个 GCP 服务帐户。
您可以通过以下方式配置身份验证GcpComputeAuthenticationOptions
.
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
GcpComputeAuthenticationOptions options = GcpComputeAuthenticationOptions.builder()
.role(…).build();
GcpComputeAuthentication authentication = new GcpComputeAuthentication(options,
restOperations());
}
// …
}
另见:
GCP-IAM 身份验证
gcp 身份验证后端允许使用现有的 GCP (Google Cloud Platform) IAM 和 GCE 凭据登录 Vault。
GCP IAM 身份验证以 JSON Web Tokens (JWT) 的形式创建签名对于服务帐户。服务帐户的 JWT 通过以下方式获取调用 GCP IAM 的projects.serviceAccounts.signJwt
应用程序接口。 调用方针对 GCP IAM 进行身份验证,从而证明其身份。此 Vault 后端将 GCP 视为受信任的第三方。
IAM 凭证可以从运行时环境获取或作为 e.g. JSON 从外部提供。JSON 是首选形式,因为它携带调用所需的项目 ID 和服务帐户标识符projects.serviceAccounts.signJwt
.
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
GcpIamCredentialsAuthenticationOptions options = GcpIamCredentialsAuthenticationOptions.builder()
.role(…).credential(GoogleCredentials.getApplicationDefault()).build();
GcpIamCredentialsAuthentication authentication = new GcpIamCredentialsAuthentication(options,
restOperations());
}
// …
}
GcpIamCredentialsAuthenticationOptions
需要 Google Cloud Java SDK 依赖项 (com.google.cloud:google-cloud-iamcredentials
) 因为身份验证实现使用 Google API 进行凭据和 JWT 签名。
您可以通过以下方式配置身份验证GcpIamCredentialsAuthenticationOptions
.
Google 凭据需要 OAuth 2 Tokens来维护Tokens生命周期。所有 API
因此是同步的,GcpIamCredentialsAuthentication 不支持AuthenticationSteps 这是
需要被动使用。 |
GcpIamCredentialsAuthentication 使用 IAM 凭证 API,并且是使用GcpIamAuthentication 使用已弃用的 IAM API。 |
另见:
GitHub 身份验证
github auth 后端提供了基于 GitHub Tokens的身份验证机制。 Vault 不支持生成 GitHub Tokens的 OAuth 工作流程, 因此它不充当 GitHub 应用程序。
身份验证机制需要 GitHub Tokens(或提供商) 将Tokens传递给 Vault,然后 Vault 对您的 GitHub 进行身份验证 帐户。
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
GitHubAuthentication options = GitHubAuthentication.builder()
.token(…).build();
return new GitHubAuthentication(options, restOperations());
}
// …
}
另见:
PCF 身份验证
pcf 身份验证后端允许 PCF 实例的 Vault 登录。 它利用 PCF 的应用程序和容器身份保证。
PCF 身份验证使用实例密钥和证书创建由 Vault 验证的签名。 如果签名匹配,并且可能绑定组织/空间/应用程序 ID 匹配,Vault 将颁发适当范围的Tokens。
实例凭据可从以下文件中获得:CF_INSTANCE_CERT
和CF_INSTANCE_KEY
变量。
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
PcfAuthenticationOptions options = PcfAuthenticationOptions.builder()
.role(…).build();
PcfAuthentication authentication = new PcfAuthentication(options,
restOperations());
}
// …
}
PcfAuthenticationOptions
需要 BouncyCastle 库来创建 RSA-PSS 签名。
您可以通过以下方式配置身份验证PcfAuthenticationOptions
.
另见:
TLS 证书身份验证
这cert
身份验证后端允许使用 SSL/TLS 客户端进行身份验证
由 CA 签名或自签名的证书。
启用cert
身份验证,您需要:
-
使用 SSL,请参阅 [vault.client-ssl]
-
配置 Java
Keystore
包含客户端 证书和私钥
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
ClientCertificateAuthenticationOptions options = ClientCertificateAuthenticationOptions.builder()
.path(…).build();
return new ClientCertificateAuthentication(options, restOperations());
}
// …
}
另请参阅:Vault 文档:使用证书身份验证后端
Cubbyhole 身份验证
Cubbyhole 身份验证使用 Vault 基元提供安全身份验证
工作流程。Cubbyhole 身份验证使用Tokens作为主要登录方法。
临时Tokens用于从 Vault 的
Cubbyhole 秘密后端。登录Tokens的寿命通常较长,并且用于
与 Vault 交互。登录Tokens可以从包装的
响应或来自data
部分。
创建包装Tokens
用于创建Tokens的响应包装需要 Vault 0.6.0 或更高版本。 |
$ vault token-create -wrap-ttl="10m"
Key Value
--- -----
wrapping_token: 397ccb93-ff6c-b17b-9389-380b01ca2645
wrapping_token_ttl: 0h10m0s
wrapping_token_creation_time: 2016-09-18 20:29:48.652957077 +0200 CEST
wrapped_accessor: 46b6aebb-187f-932a-26d7-4f3d86a68319
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
CubbyholeAuthenticationOptions options = CubbyholeAuthenticationOptions
.builder()
.initialToken(VaultToken.of("…"))
.wrapped()
.build();
return new CubbyholeAuthentication(options, restOperations());
}
// …
}
使用存储的Tokens
$ vault token create
Key Value
--- -----
token f9e30681-d46a-cdaf-aaa0-2ae0a9ad0819
token_accessor 4eee9bd9-81bb-06d6-af01-723c54a72148
token_duration 0s
token_renewable false
token_policies [root]
$ vault token create -use-limit=2 -orphan -no-default-policy -policy=none
Key Value
--- -----
token 895cb88b-aef4-0e33-ba65-d50007290780
token_accessor e84b661c-8aa8-2286-b788-f258f30c8325
token_duration 0s
token_renewable false
token_policies [none]
$ export VAULT_TOKEN=895cb88b-aef4-0e33-ba65-d50007290780
$ vault write cubbyhole/token token=f9e30681-d46a-cdaf-aaa0-2ae0a9ad0819
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
CubbyholeAuthenticationOptions options = CubbyholeAuthenticationOptions
.builder()
.initialToken(VaultToken.of("…"))
.path("cubbyhole/token")
.build();
return new CubbyholeAuthentication(options, restOperations());
}
// …
}
剩余 TTL/可续订性
从 Cubbyhole 检索到的与非零 TTL 关联的Tokens从 Tokens创建时间。该时间不一定与申请相同 启动。为了补偿初始延迟,Cubbyhole 身份验证执行 自查找与非零 TTL 关联的Tokens,以检索剩余的 TTL。 Cubbyhole 身份验证不会在没有 TTL 的情况下自查找包装的Tokens,因为 零 TTL 表示没有关联的 TTL。
非包装Tokens不提供有关可续订性和 TTL 的详细信息,仅 检索Tokens。自查找将查找可续订性和剩余 TTL。
另见:
JWT 身份验证
配置 JWT 身份验证需要Tokens或 JWT 提供商。
您可以通过以下方式配置身份验证JwtAuthenticationOptions
.
在 Vault 端,您可以通过启用 JWT 身份验证后端并创建角色来配置 JWT 后端。您可以使用oidc_discovery_url
,jwks_url
或jwt_validation_pubkeys
以配置 JWT 后端。
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
JwtAuthenticationOptions options = JwtAuthenticationOptions.builder()
.role(…).jwt(…).path(…).build();
return new JwtAuthentication(options, restOperations());
}
// …
}
另见:
Kubernetes 身份验证
Vault 从 0.8.3 开始支持使用 Kubernetes Tokens进行基于 Kubernetes 的身份验证。
使用 Kubernetes 身份验证需要 Kubernetes 服务帐户Tokens,通常挂载在/var/run/secrets/kubernetes.io/serviceaccount/token
. 该文件包含读取并发送到 Vault 的Tokens。Vault 在登录期间使用 Kubernetes 的 API 验证其有效性。
配置 Kubernetes 身份验证至少需要提供角色名称:
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
KubernetesAuthenticationOptions options = KubernetesAuthenticationOptions.builder()
.role(…).jwtSupplier(…).build();
return new KubernetesAuthentication(options, restOperations());
}
// …
}
您可以通过以下方式配置身份验证KubernetesAuthenticationOptions
.
另见:
用户名/密码认证
用户名/密码通常是最终用户身份验证方案。 多个 Vault 身份验证后端支持使用用户名和密码:
-
用户名和密码 (
userpass
) -
LDAP (
ldap
) -
奥克塔 (
okta
,支持额外的基于时间的一次性Tokens) -
半径 (
radius
)
UserPasswordAuthenticationOptions
可以与上述所有身份验证后端一起使用,因为登录 API 在所有机制上都是相似的。
配置时请确保使用适当的身份验证挂载路径UserPasswordAuthenticationOptions
.
UserPasswordAuthentication
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
UserPasswordAuthenticationOptions options = UserPasswordAuthenticationOptions.builder()
.username(…).password(…).build();
return new UserPasswordAuthentication(options, restOperations());
}
// …
}
另见:
身份验证步骤
ClientAuthentication
对象描述身份验证流程并执行实际的
身份验证步骤。预先组合的身份验证易于使用和配置
与同步执行的紧密绑定。
身份验证方法的组成和重复使用常见步骤,例如发布登录
无意将有效负载发送到 Vault 或从 HTTP 源检索身份验证输入
跟ClientAuthentication
对象。
身份验证步骤提供常见身份验证活动的可重用性。
通过以下方式创建的步骤AuthenticationSteps
描述功能中的身份验证流
样式,将实际的身份验证执行留给特定的执行器。
AuthenticationSteps.just(VaultToken.of(…)); (1)
1 | 创建AuthenticationSteps 从一个VaultToken . |
可以从单个输入创建单步身份验证流。声明的流
多个身份验证步骤以Supplier
或HttpRequest
提供
身份验证状态对象,可用于映射或发布到 Vault 进行登录。
AuthenticationSteps.fromSupplier( (1)
() -> getAppRoleLogin(options.getRoleId(), options.getSecretId())) (2)
.login("auth/{mount}/login", options.getPath()); (3)
1 | 开始声明AuthenticationSteps 接受Supplier<T> .
状态对象类型取决于Supplier 响应类型,可以在后续步骤中映射。 |
2 | 实际的Supplier 实现。
创建Map 在这种情况下。 |
3 | 通过发布状态对象 (Map ) 添加到 Vault 端点以创建 Vault Tokens。
请注意,模板变量受 URL 转义的影响。 |
身份验证流需要执行程序来执行实际登录。我们提供两个执行者 对于不同的执行模型:
-
AuthenticationStepsExecutor
作为同步的直接替代品ClientAuthentication
. -
AuthenticationStepsOperator
用于反应性执行。
多ClientAuthentication
自带静态工厂方法来创建AuthenticationSteps
对于特定于身份验证的选项:
AuthenticationSteps
执行CubbyholeAuthenticationOptions options = …
RestOperations restOperations = …
AuthenticationSteps steps = CubbyholeAuthentication.createAuthenticationSteps(options);
AuthenticationStepsExecutor executor = new AuthenticationStepsExecutor(steps, restOperations);
VaultToken token = executor.login();
Tokens生命周期
Vault 的Tokens可以与生存时间相关联。通过身份验证方法获取的Tokens 只要会话处于活动状态,就可以使用,并且在应用程序处于活动状态时不应过期。
Spring Vault 提供了LifecycleAwareSessionManager
一个会话管理器,可以续订Tokens,直到它达到其终端 TTL,然后执行另一次登录以获取与会话关联的下一个Tokens。
根据身份验证方法,登录可以创建两种Tokens:
-
VaultToken
:封装实际Tokens的通用Tokens。 -
LoginToken
:与可续订性/TTL 关联的Tokens。
身份验证方法,例如TokenAuthentication
只需创建一个VaultToken
不包含任何可续订性/TTL 详细信息。LifecycleAwareSessionManager
将对Tokens运行自查找,以从 Vault 检索可续订性和 TTL。VaultToken
如果启用了自查找,则会定期续订。请注意VaultToken
永远不会被撤销,只有LoginToken
被撤销。
创建身份验证方法LoginToken
直接(所有基于登录的身份验证方法)已经提供了设置Tokens续订所需的所有详细信息。从登录中获取的Tokens由LifecycleAwareSessionManager
如果会话管理器已关闭。