|
该版本仍在开发中,尚未被视为稳定。最新稳定版请使用Spring Vault 4.0.0! |
认证方法
不同组织对安全有不同的要求 以及认证。Vault 通过多重认证反映了这一需求 方法。Spring Vault 支持多种认证机制。
外部化登录凭证
首次获得安全系统的访问权限称为安全引入。 任何客户端都需要临时或永久凭证才能访问Vault。外部化凭证 这是一个有助于保持代码可维护性高的模式,但也存在更高的披露风险。
向任何一方披露登录凭证即可登录Vault并访问 由底层角色允许。选择合适的客户端认证和 向申请注入资质需进行风险评估。
Spring的PropertySource抽象是自然而然的契合 这样可以让配置不在应用代码之外。你可以使用系统属性、环境 变量或属性文件用于存储登录凭证。每种方法都有其独特的特性。 请记住,命令行和环境属性可以通过适当的方式进行内省 作系统访问等级。
vault.token(金库Tokens)映射到属性文件@PropertySource("configuration.properties")
@Configuration
public class Config extends AbstractVaultConfiguration {
@Override
public ClientAuthentication clientAuthentication() {
return new TokenAuthentication(getEnvironment().getProperty("vault.token"));
}
}
Spring允许多种方式获得环境.使用VaultPropertySource,通过@Autowired 环境不会提供环境由于环境工程仍在施工中,自动布线则在后期才会实施。你的配置类应该更适合实现应用上下文感知并得到环境从应用上下文. |
看SecurePropertyUsage.java对于一个关于引用组件及其他属性源属性的样本。
Tokens认证
Tokens是 Vault 内部认证的核心方法。 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 认证后端提供了安全的引入机制 适用于AWS EC2实例,允许自动检索Vault。 Tokens。与大多数Vault认证后端不同,这个后端 无需先部署或安全敏感配置 凭证(Tokens、用户名/密码、客户端证书等)。 相反,它将AWS视为可信第三方,并使用 加密签名的动态元数据信息,具有独特的特性 表示每个EC2实例。
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
return new AwsEc2Authentication(restOperations());
}
// …
}
AWS-EC2认证默认启用nonx,可以跟随其后 即首次使用信任原则(TOFU)。任何非意愿的当事人 获得PKCS#7身份元数据访问权限可以进行身份验证 对阵Vault。
在第一次登录时,Spring Vault 生成了一个 nonce 它存储在认证后端,除了实例 Id。 重新认证需要发送相同的 nonce。任何其他情况 队伍没有无念,可以在金库中发出警报 进一步调查。
nonce 被存储在内存中,并在应用重启时丢失。
自 Spring Vault 3.2 起,AWS-EC2 认证支持请求/响应 (IMDSv1)元数据检索和基于会话的变体(IMDSv2)。
AWS-EC2 认证角色是可选的,默认使用 AMI。
你可以通过设置来配置认证角色
它AwsEc2AuthenticationOptions(AwsEc2AuthenticationOptions).
AWS-IAM 认证
AWS 认证后端允许使用现有的 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());
}
// …
}
AwsIam认证需要依赖AWS Java SDK(com.amazonaws:aws-java-sdk-core) 因为认证实现使用AWS SDK类型进行凭证和请求签名。
你可以配置认证AwsIamAuthenticationOptions(AwsIamAuthenticationOptions).
参见:
Azure (MSI) authentication
Azure 认证后端为 Azure 虚拟机实例提供了安全的引入机制允许自动检索 Vault Tokens。 与大多数Vault认证后端不同,该后端不需要优先部署或配置安全敏感的凭证(Tokens、用户名/密码、客户端证书等)。相反,它将Azure视为可信第三方,并使用托管服务身份和实例元数据信息,这些信息可以绑定到虚拟机实例。
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
AzureMsiAuthenticationOptions options = AzureMsiAuthenticationOptions.builder()
.role(…).build();
return new AzureMsiAuthentication(options, restOperations());
}
// …
}
Azure 认证需要关于虚拟机环境的详细信息(订阅 ID,资源组名称、虚拟机名称)。这些细节可以通过以下方式配置AzureMsiAuthenticationOptionsBuilder. 如果不加以调整,AzureMsiAuthentication查询 Azure 的实例元数据服务以获取获取这些详细信息。
参见:
GCP-GCE 认证
GCP认证后端允许通过现有的GCP(Google Cloud Platform)IAM和GCE凭证进行Vault登录。
GCP GCE(谷歌计算引擎)认证创建一个签名,形式为服务账户的 JSON Web Tokens(JWT)。计算引擎实例的 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());
}
// …
}
GcpIam凭证认证选项需要 Google Cloud Java SDK 依赖 (com.google.cloud:google-cloud-iamcredentials) 因为认证实现使用Google API进行凭证和JWT签名。
你可以配置认证GcpIam凭证认证选项.
Google 凭证需要一个 OAuth 2 Tokens来维持Tokens生命周期。所有 API都是同步的,因此,GcpIam凭证认证不支持认证步骤这是响应式使用所必需的。 |
GcpIam凭证认证使用 IAM 凭证 API,并用 替代已弃用的GcpIam认证使用已弃用的IAM API。 |
参见:
GitHub 认证
GitHub 认证后端提供基于 GitHub Tokens的认证机制。 Vault 不支持 OAuth 工作流程来生成 GitHub Tokens, 所以它并不是一个GitHub应用。
认证机制需要GitHubTokens(或提供商) 将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());
}
// …
}
Pcf认证选项创建RSA-PSS签名需要BouncyCastle库。
你可以配置认证Pcf认证选项.
参见:
TLS证书认证
这证书认证后端允许使用 SSL/TLS 客户端进行身份验证
这些证书要么由CA签署,要么由CA自签名。
以实现证书你需要进行以下认证:
-
使用SSL,参见[vault.client-ssl]
-
配置一个Java
密钥存储包含客户端 证书与私钥
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
ClientCertificateAuthenticationOptions options = ClientCertificateAuthenticationOptions.builder()
.path(…).build();
return new ClientCertificateAuthentication(options, restOperations());
}
// …
}
格子认证
Cubbyhole 认证使用 Vault 原语来提供安全的认证
工作流程。Bootbyhole认证使用Tokens作为主要登录方式。
临时Tokens用于从Vault获取第二个登录VaultToken。
Bootbyhole秘密后端。登录Tokens通常寿命更长,并用于
与Vault互动。登录Tokens可以从包裹的
回应或来自数据部分。
创建包裹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制作时间。这个时间不一定等同于实际应用 启动。为了弥补初始延迟,Grabbyhole 认证执行 对非零 TTL 关联的标记进行自我查找,以获取剩余的 TTL。 Bootbyhole 认证不会在没有 TTL 的情况下自查包裹后的Tokens,因为 0 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 的认证,使用KubernetesTokens。
使用 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认证后端支持使用用户名和密码:
-
用户名和密码(
用户通行证) -
LDAP(
LDAP) -
奥克塔(
八,支持基于时间的一次性Tokens) -
半径(
半径)
用户密码认证选项可以与上述所有认证后端一起使用,因为登录 API 在所有机制中都相似。
配置时请确保使用正确的认证挂载路径用户密码认证选项.
用户密码认证@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
UserPasswordAuthenticationOptions options = UserPasswordAuthenticationOptions.builder()
.username(…).password(…).build();
return new UserPasswordAuthentication(options, restOperations());
}
// …
}
参见:
认证步骤
客户端认证对象描述认证流程并执行实际作
认证步骤。预组认证易于使用且易于配置
与同步执行紧密绑定。
认证方法的组合以及重复使用常见步骤,如发布登录
本意是将有效载荷发送到Vault或从HTTP源获取认证输入
跟客户端认证对象。
认证步骤提供了共同认证活动的可重复使用性。
通过以下方式创建的步骤认证步骤描述函数中的认证流程
Style将实际的认证执行留给特定的执行者。
AuthenticationSteps.just(VaultToken.of(…)); (1)
| 1 | 创建认证步骤仅仅是VaultToken(金库Tokens). |
单步认证流程可以从单一输入创建。流声明
多重认证步骤以提供商或HttpRequest提供
认证状态对象,可用于映射或发布到Vault登录。
AuthenticationSteps.fromSupplier( (1)
() -> getAppRoleLogin(options.getRoleId(), options.getSecretId())) (2)
.login("auth/{mount}/login", options.getPath()); (3)
| 1 | 开始宣告认证步骤接受提供商<T>.
状态对象类型依赖于提供商响应类型,可以在后续步骤中映射。 |
| 2 | 实际提供商实现。
创建地图在这种情况下。 |
| 3 | 通过发布状态对象(地图)连接到用于创建 Vault Tokens的 Vault 端点。
注意模板变量会被URL转义。 |
认证流程需要执行者实际登录。我们提供两名执行人 针对不同执行模型:
-
认证步骤执行者作为同步的直接替换客户端认证. -
认证步骤操作员用于响应式执行。
多客户端认证带有静态工厂方法来制造认证步骤针对认证专用选项:
认证步骤执行CubbyholeAuthenticationOptions options = …
RestOperations restOperations = …
AuthenticationSteps steps = CubbyholeAuthentication.createAuthenticationSteps(options);
AuthenticationStepsExecutor executor = new AuthenticationStepsExecutor(steps, restOperations);
VaultToken token = executor.login();
Tokens生命周期
Vault的Tokens可以与“活着的时代”相关联。通过认证方法获得的Tokens 设计为只要会话处于激活状态即可使用,且应用程序在激活期间不应失效。
春季金库提供了LifecycleAwareSessionManager一个会话管理器,可以续签Tokens直到达到终端TTL,然后进行再次登录以获取与会话关联的下一个Tokens。
根据认证方式的不同,登录可以创建两种Tokens:
-
VaultToken(金库Tokens): 通用Tokens封装实际Tokens。 -
登录Tokens:与续期/TTL相关的Tokens。
认证方法包括Tokens认证只要创建一个VaultToken(金库Tokens)该账户不包含任何续期或TTL细节。LifecycleAwareSessionManager会对Tokens进行自我查找,以从Vault获取可续期性和TTL。VaultToken(金库Tokens)如果启用了自我查找,则会定期更新。注意VaultToken(金库Tokens)从未被撤销,只是登录Tokens被撤销。
认证方法的创建登录Tokens所有基于登录的认证方法都已直接提供设置Tokens续期所需的所有细节。登录获得的Tokens会被以下方式撤销LifecycleAwareSessionManager如果会话管理器被关闭。