认证方法
不同组织对安全有不同的要求 以及认证。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 VM实例,允许自动检索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.
如果不加以调整,AzureMsiAuthenticationqueries Azure's instance metadata service to
获取这些详细信息。
参见:
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 IAMprojects.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 签署或自签名。
以实现证书你需要进行以下认证:
-
使用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 原语来提供安全的认证工作流程。Cubbyhole 认证使用Tokens作为主要登录方式。临时Tokens用于从 Vault 的Cubbyhole 秘密后端获取第二个登录 VaultToken 。登录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/可续航时间
从与非零TTL关联的Bootbyhole检索的Tokens,其TTL从Tokens创建时间开始。该时间不一定与应用时间相同 启动。 为弥补初始延迟,Cubbyhole认证会执行对与非零TTL相关的Tokens进行自查找,以获取剩余的TTL。Cubbyhole认证不会在没有TTL的情况下自查找包裹Tokens,因为0 TTL表示没有关联的TTL。
非封装Tokens仅通过检索Tokens,无法提供关于可续性和TTL的详细信息。自查会查找可续性和剩余的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如果会话管理器被关闭。