com.aliyun.auth.credentials.provider.OIDCRoleArnCredentialProvider Maven / Gradle / Ivy
The newest version!
package com.aliyun.auth.credentials.provider;
import com.aliyun.auth.credentials.Credential;
import com.aliyun.auth.credentials.ICredential;
import com.aliyun.auth.credentials.exception.CredentialException;
import com.aliyun.auth.credentials.http.*;
import com.aliyun.auth.credentials.utils.AuthUtils;
import com.aliyun.auth.credentials.utils.ParameterHelper;
import com.aliyun.auth.credentials.utils.RefreshResult;
import com.aliyun.core.utils.StringUtils;
import com.google.gson.Gson;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
public class OIDCRoleArnCredentialProvider extends HttpCredentialProvider {
/**
* Default duration for started sessions. Unit of Second
*/
private int durationSeconds;
/**
* The arn of the role to be assumed.
*/
private String roleArn;
private String oidcProviderArn;
private String oidcTokenFilePath;
/**
* An identifier for the assumed role session.
*/
private final String roleSessionName;
private String policy;
/**
* Unit of millisecond
*/
private int connectionTimeout;
private int readTimeout;
/**
* Endpoint of RAM OpenAPI
*/
private final String stsEndpoint;
private final CompatibleUrlConnClient client;
private String protocol = "https";
private OIDCRoleArnCredentialProvider(BuilderImpl builder) {
super(builder);
this.roleSessionName = builder.roleSessionName == null ? !StringUtils.isEmpty(AuthUtils.getEnvironmentRoleSessionName()) ?
AuthUtils.getEnvironmentRoleSessionName() : "aliyun-java-auth-" + System.currentTimeMillis() : builder.roleSessionName;
this.durationSeconds = builder.durationSeconds == null ? 3600 : builder.durationSeconds;
if (this.durationSeconds < 900) {
throw new IllegalArgumentException("Session duration should be in the range of 900s - max session duration.");
}
this.roleArn = builder.roleArn == null ? AuthUtils.getEnvironmentRoleArn() : builder.roleArn;
if (StringUtils.isEmpty(this.roleArn)) {
throw new IllegalArgumentException("RoleArn or environment variable ALIBABA_CLOUD_ROLE_ARN cannot be empty.");
}
this.oidcProviderArn = builder.oidcProviderArn == null ? AuthUtils.getEnvironmentOIDCProviderArn() : builder.oidcProviderArn;
if (StringUtils.isEmpty(this.oidcProviderArn)) {
throw new IllegalArgumentException("OIDCProviderArn or environment variable ALIBABA_CLOUD_OIDC_PROVIDER_ARN cannot be empty.");
}
this.oidcTokenFilePath = builder.oidcTokenFilePath == null ? AuthUtils.getEnvironmentOIDCTokenFilePath() : builder.oidcTokenFilePath;
if (StringUtils.isEmpty(this.oidcTokenFilePath)) {
throw new IllegalArgumentException("OIDCTokenFilePath or environment variable ALIBABA_CLOUD_OIDC_TOKEN_FILE cannot be empty.");
}
this.policy = builder.policy;
this.connectionTimeout = builder.connectionTimeout == null ? 5000 : builder.connectionTimeout;
this.readTimeout = builder.readTimeout == null ? 10000 : builder.readTimeout;
if (!StringUtils.isEmpty(builder.stsEndpoint)) {
this.stsEndpoint = builder.stsEndpoint;
} else {
String prefix = builder.enableVpc != null ? (builder.enableVpc ? "sts-vpc" : "sts") : AuthUtils.isEnableVpcEndpoint() ? "sts-vpc" : "sts";
if (!StringUtils.isEmpty(builder.stsRegionId)) {
this.stsEndpoint = String.format("%s.%s.aliyuncs.com", prefix, builder.stsRegionId);
} else if (!StringUtils.isEmpty(AuthUtils.getEnvironmentSTSRegion())) {
this.stsEndpoint = String.format("%s.%s.aliyuncs.com", prefix, AuthUtils.getEnvironmentSTSRegion());
} else {
this.stsEndpoint = "sts.aliyuncs.com";
}
}
this.client = new CompatibleUrlConnClient();
this.buildRefreshCache();
}
public static Builder builder() {
return new BuilderImpl();
}
public String getStsEndpoint() {
return this.stsEndpoint;
}
@Override
public RefreshResult refreshCredentials() {
String oidcToken = AuthUtils.getOIDCToken(oidcTokenFilePath);
ParameterHelper parameterHelper = new ParameterHelper();
HttpRequest httpRequest = new HttpRequest();
httpRequest.setUrlParameter("Action", "AssumeRoleWithOIDC");
httpRequest.setUrlParameter("Format", "JSON");
httpRequest.setUrlParameter("Version", "2015-04-01");
Map body = new HashMap();
body.put("DurationSeconds", String.valueOf(durationSeconds));
body.put("RoleArn", this.roleArn);
body.put("OIDCProviderArn", this.oidcProviderArn);
body.put("OIDCToken", oidcToken);
body.put("RoleSessionName", this.roleSessionName);
body.put("Policy", this.policy);
try {
StringBuilder content = new StringBuilder();
boolean first = true;
for (Map.Entry entry : body.entrySet()) {
if (StringUtils.isEmpty(entry.getValue())) {
continue;
}
if (first) {
first = false;
} else {
content.append("&");
}
content.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
content.append("=");
content.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
}
httpRequest.setHttpContent(content.toString().getBytes("UTF-8"), "UTF-8", FormatType.FORM);
} catch (UnsupportedEncodingException e) {
throw new CredentialException(String.format("Error refreshing credentials from OIDC: %s.", e.getMessage()));
}
httpRequest.setSysMethod(MethodType.POST);
httpRequest.setSysConnectTimeout(this.connectionTimeout);
httpRequest.setSysReadTimeout(this.readTimeout);
httpRequest.setSysUrl(parameterHelper.composeUrl(this.stsEndpoint, httpRequest.getUrlParameters(),
protocol));
HttpResponse httpResponse;
try {
httpResponse = client.syncInvoke(httpRequest);
} catch (Exception e) {
throw new CredentialException("Failed to connect OIDC Service: " + e);
}
if (httpResponse.getResponseCode() != 200) {
throw new CredentialException(String.format("Error refreshing credentials from OIDC, HttpCode: %s, result: %s.", httpResponse.getResponseCode(), httpResponse.getHttpContentString()));
}
Gson gson = new Gson();
Map map = gson.fromJson(httpResponse.getHttpContentString(), Map.class);
if (null == map || !map.containsKey("Credentials")) {
throw new CredentialException(String.format("Error retrieving credentials from OIDC result: %s.", httpResponse.getHttpContentString()));
}
Map result = (Map) map.get("Credentials");
if (!result.containsKey("AccessKeyId") || !result.containsKey("AccessKeySecret") || !result.containsKey("SecurityToken")) {
throw new CredentialException(String.format("Error retrieving credentials from OIDC result: %s.", httpResponse.getHttpContentString()));
}
Instant expiration = ParameterHelper.getUTCDate(result.get("Expiration")).toInstant();
ICredential credential = Credential.builder()
.accessKeyId(result.get("AccessKeyId"))
.accessKeySecret(result.get("AccessKeySecret"))
.securityToken(result.get("SecurityToken"))
.build();
return RefreshResult.builder(credential)
.staleTime(getStaleTime(expiration))
.prefetchTime(getPrefetchTime(expiration))
.build();
}
@Override
public void close() {
super.close();
this.client.close();
}
public interface Builder extends HttpCredentialProvider.Builder {
Builder roleSessionName(String roleSessionName);
Builder durationSeconds(Integer durationSeconds);
Builder roleArn(String roleArn);
Builder oidcProviderArn(String oidcProviderArn);
Builder oidcTokenFilePath(String oidcTokenFilePath);
Builder policy(String policy);
Builder connectionTimeout(Integer connectionTimeout);
Builder readTimeout(Integer readTimeout);
Builder stsEndpoint(String stsEndpoint);
Builder stsRegionId(String stsRegionId);
Builder enableVpc(Boolean enableVpc);
@Override
OIDCRoleArnCredentialProvider build();
}
private static final class BuilderImpl
extends HttpCredentialProvider.BuilderImpl
implements Builder {
private String roleSessionName;
private Integer durationSeconds;
private String roleArn;
private String oidcProviderArn;
private String oidcTokenFilePath;
private String policy;
private Integer connectionTimeout;
private Integer readTimeout;
private String stsEndpoint;
private String stsRegionId;
private Boolean enableVpc;
public Builder roleSessionName(String roleSessionName) {
this.roleSessionName = roleSessionName;
return this;
}
public Builder durationSeconds(Integer durationSeconds) {
this.durationSeconds = durationSeconds;
return this;
}
public Builder roleArn(String roleArn) {
this.roleArn = roleArn;
return this;
}
public Builder oidcProviderArn(String oidcProviderArn) {
this.oidcProviderArn = oidcProviderArn;
return this;
}
public Builder oidcTokenFilePath(String oidcTokenFilePath) {
this.oidcTokenFilePath = oidcTokenFilePath;
return this;
}
public Builder policy(String policy) {
this.policy = policy;
return this;
}
public Builder connectionTimeout(Integer connectionTimeout) {
this.connectionTimeout = connectionTimeout;
return this;
}
public Builder readTimeout(Integer readTimeout) {
this.readTimeout = readTimeout;
return this;
}
public Builder stsEndpoint(String stsEndpoint) {
this.stsEndpoint = stsEndpoint;
return this;
}
public Builder stsRegionId(String stsRegionId) {
this.stsRegionId = stsRegionId;
return this;
}
public Builder enableVpc(Boolean enableVpc) {
this.enableVpc = enableVpc;
return this;
}
@Override
public OIDCRoleArnCredentialProvider build() {
return new OIDCRoleArnCredentialProvider(this);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy