diff --git a/pom.xml b/pom.xml index e28aae9..ae46487 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.aliyun credentials-java - 0.3.12 + 1.0.0 jar credentials-java @@ -54,11 +54,18 @@ + 8 + 8 2.0.2 3.0.0 + + com.aliyun + credentials-api + 1.0.0 + com.aliyun tea @@ -138,8 +145,8 @@ maven-compiler-plugin 3.13.0 - 1.7 - 1.7 + ${maven.compiler.source} + ${maven.compiler.target} UTF-8 diff --git a/src/main/java/com/aliyun/credentials/Client.java b/src/main/java/com/aliyun/credentials/Client.java index ad01466..2caef13 100644 --- a/src/main/java/com/aliyun/credentials/Client.java +++ b/src/main/java/com/aliyun/credentials/Client.java @@ -5,6 +5,7 @@ import com.aliyun.credentials.models.CredentialModel; import com.aliyun.credentials.provider.*; import com.aliyun.credentials.utils.AuthConstant; +import com.aliyun.credentials.utils.ProviderName; import com.aliyun.credentials.utils.StringUtils; import com.aliyun.tea.utils.Validate; @@ -37,6 +38,7 @@ private AlibabaCloudCredentialsProvider getProvider(Config config) { .accessKeySecret(Validate.notNull( config.accessKeySecret, "AccessKeySecret must not be null.")) .type(config.type) + .providerName(ProviderName.STATIC_AK) .build()) .build(); case AuthConstant.STS: @@ -49,6 +51,7 @@ private AlibabaCloudCredentialsProvider getProvider(Config config) { .securityToken(Validate.notNull( config.securityToken, "SecurityToken must not be null.")) .type(config.type) + .providerName(ProviderName.STATIC_STS) .build()) .build(); case AuthConstant.BEARER: @@ -76,6 +79,7 @@ private AlibabaCloudCredentialsProvider getProvider(Config config) { .accessKeySecret(Validate.notNull( config.accessKeySecret, "AccessKeySecret must not be null.")) .type(AuthConstant.ACCESS_KEY) + .providerName(ProviderName.STATIC_AK) .build()) .build(); } else { @@ -88,6 +92,7 @@ private AlibabaCloudCredentialsProvider getProvider(Config config) { .securityToken(Validate.notNull( config.securityToken, "SecurityToken must not be null.")) .type(AuthConstant.STS) + .providerName(ProviderName.STATIC_STS) .build()) .build(); } diff --git a/src/main/java/com/aliyun/credentials/models/Config.java b/src/main/java/com/aliyun/credentials/models/Config.java index b0ea5e0..7973117 100644 --- a/src/main/java/com/aliyun/credentials/models/Config.java +++ b/src/main/java/com/aliyun/credentials/models/Config.java @@ -22,7 +22,7 @@ public class Config extends TeaModel { @NameInMap("roleName") public String roleName; @NameInMap("disableIMDSv1") - public Boolean disableIMDSv1 = false; + public Boolean disableIMDSv1; @NameInMap("enableIMDSv2") public Boolean enableIMDSv2; @NameInMap("metadataTokenDuration") @@ -34,9 +34,9 @@ public class Config extends TeaModel { @NameInMap("host") public String host; @NameInMap("readTimeout") - public int timeout = 10000; + public Integer timeout; @NameInMap("connectTimeout") - public int connectTimeout = 5000; + public Integer connectTimeout; @NameInMap("proxy") public String proxy; @NameInMap("policy") @@ -50,7 +50,7 @@ public class Config extends TeaModel { @NameInMap("credentialsURI") public String credentialsURI; @NameInMap("STSEndpoint") - public String STSEndpoint = "sts.aliyuncs.com"; + public String STSEndpoint; /** *

external id for ram role arn

*/ @@ -243,7 +243,7 @@ public Config setTimeout(int timeout) { return this; } - public int getTimeout() { + public Integer getTimeout() { return timeout; } @@ -252,7 +252,7 @@ public Config setConnectTimeout(int connectTimeout) { return this; } - public int getConnectTimeout() { + public Integer getConnectTimeout() { return connectTimeout; } diff --git a/src/main/java/com/aliyun/credentials/models/CredentialModel.java b/src/main/java/com/aliyun/credentials/models/CredentialModel.java index 3df5df3..5037696 100644 --- a/src/main/java/com/aliyun/credentials/models/CredentialModel.java +++ b/src/main/java/com/aliyun/credentials/models/CredentialModel.java @@ -2,14 +2,16 @@ package com.aliyun.credentials.models; import com.aliyun.credentials.AlibabaCloudCredentials; +import com.aliyun.credentials.api.ICredentials; import com.aliyun.tea.*; -public class CredentialModel extends TeaModel implements AlibabaCloudCredentials { +public class CredentialModel extends TeaModel implements AlibabaCloudCredentials, ICredentials { public String accessKeyId; public String accessKeySecret; public String securityToken; public String bearerToken; public String type; + public String providerName; public long expiration; private CredentialModel(Builder builder) { @@ -18,6 +20,7 @@ private CredentialModel(Builder builder) { this.securityToken = builder.securityToken; this.bearerToken = builder.bearerToken; this.type = builder.type; + this.providerName = builder.providerName; this.expiration = builder.expiration; } @@ -79,12 +82,18 @@ public String getBearerToken() { return this.bearerToken; } + @Override + public String getProviderName() { + return providerName; + } + public static final class Builder { private String accessKeyId; private String accessKeySecret; private String securityToken; private String bearerToken; private String type; + private String providerName; private long expiration; public Builder accessKeyId(String accessKeyId) { @@ -112,6 +121,11 @@ public Builder type(String type) { return this; } + public Builder providerName(String providerName) { + this.providerName = providerName; + return this; + } + public Builder expiration(long expiration) { this.expiration = expiration; return this; diff --git a/src/main/java/com/aliyun/credentials/provider/AlibabaCloudCredentialsProvider.java b/src/main/java/com/aliyun/credentials/provider/AlibabaCloudCredentialsProvider.java index 434c25a..f702390 100644 --- a/src/main/java/com/aliyun/credentials/provider/AlibabaCloudCredentialsProvider.java +++ b/src/main/java/com/aliyun/credentials/provider/AlibabaCloudCredentialsProvider.java @@ -1,8 +1,9 @@ package com.aliyun.credentials.provider; +import com.aliyun.credentials.api.ICredentialsProvider; import com.aliyun.credentials.models.CredentialModel; -public interface AlibabaCloudCredentialsProvider { +public interface AlibabaCloudCredentialsProvider extends ICredentialsProvider { CredentialModel getCredentials(); } diff --git a/src/main/java/com/aliyun/credentials/provider/CLIProfileCredentialsProvider.java b/src/main/java/com/aliyun/credentials/provider/CLIProfileCredentialsProvider.java new file mode 100644 index 0000000..116def2 --- /dev/null +++ b/src/main/java/com/aliyun/credentials/provider/CLIProfileCredentialsProvider.java @@ -0,0 +1,296 @@ +package com.aliyun.credentials.provider; + +import com.aliyun.credentials.exception.CredentialException; +import com.aliyun.credentials.models.CredentialModel; +import com.aliyun.credentials.utils.AuthConstant; +import com.aliyun.credentials.utils.AuthUtils; +import com.aliyun.credentials.utils.ProviderName; +import com.aliyun.credentials.utils.StringUtils; +import com.aliyun.tea.utils.Validate; +import com.google.gson.Gson; +import com.google.gson.annotations.SerializedName; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.util.List; + +public class CLIProfileCredentialsProvider implements AlibabaCloudCredentialsProvider { + private final String CLI_CREDENTIALS_CONFIG_PATH = System.getProperty("user.home") + + "/.aliyun/config.json"; + private volatile AlibabaCloudCredentialsProvider credentialsProvider; + private volatile String currentProfileName; + private final Object credentialsProviderLock = new Object(); + + private CLIProfileCredentialsProvider(Builder builder) { + this.currentProfileName = builder.profileName == null ? System.getenv("ALIBABA_CLOUD_PROFILE") : builder.profileName; + } + + static Builder builder() { + return new Builder(); + } + + @Override + public CredentialModel getCredentials() { + if (AuthUtils.isDisableCLIProfile()) { + throw new CredentialException("CLI credentials file is disabled."); + } + Config config = parseProfile(CLI_CREDENTIALS_CONFIG_PATH); + if (null == config) { + throw new CredentialException("Unable to get profile from empty CLI credentials file."); + } + String refreshedProfileName = System.getenv("ALIBABA_CLOUD_PROFILE"); + if (shouldReloadCredentialsProvider(refreshedProfileName)) { + synchronized (credentialsProviderLock) { + if (shouldReloadCredentialsProvider(refreshedProfileName)) { + if (!StringUtils.isEmpty(refreshedProfileName)) { + this.currentProfileName = refreshedProfileName; + } + this.credentialsProvider = reloadCredentialsProvider(config, this.currentProfileName); + } + } + } + CredentialModel credential = this.credentialsProvider.getCredentials(); + return CredentialModel.builder() + .accessKeyId(credential.getAccessKeyId()) + .accessKeySecret(credential.getAccessKeySecret()) + .securityToken(credential.getSecurityToken()) + .expiration(credential.getExpiration()) + .type(credential.getType()) + .providerName(String.format("%s/%s", this.getProviderName(), credential.getProviderName())) + .build(); + } + + AlibabaCloudCredentialsProvider reloadCredentialsProvider(Config config, String profileName) { + String currentProfileName = !StringUtils.isEmpty(profileName) ? profileName : config.getCurrent(); + List profiles = config.getProfiles(); + if (profiles != null && !profiles.isEmpty()) { + for (Profile profile : profiles) { + if (!StringUtils.isEmpty(profile.getName()) && profile.getName().equals(currentProfileName)) { + switch (profile.getMode()) { + case "AK": + return StaticCredentialsProvider.builder() + .credential(CredentialModel.builder() + .accessKeyId(Validate.notNull( + profile.getAccessKeyId(), "AccessKeyId must not be null.")) + .accessKeySecret(Validate.notNull( + profile.getAccessKeySecret(), "AccessKeySecret must not be null.")) + .type(AuthConstant.ACCESS_KEY) + .providerName(ProviderName.STATIC_AK) + .build()) + .build(); + case "RamRoleArn": + AlibabaCloudCredentialsProvider innerProvider = StaticCredentialsProvider.builder() + .credential(CredentialModel.builder() + .accessKeyId(Validate.notNull( + profile.getAccessKeyId(), "AccessKeyId must not be null.")) + .accessKeySecret(Validate.notNull( + profile.getAccessKeySecret(), "AccessKeySecret must not be null.")) + .type(AuthConstant.ACCESS_KEY) + .providerName(ProviderName.STATIC_AK) + .build()) + .build(); + ; + return RamRoleArnCredentialProvider.builder() + .credentialsProvider(innerProvider) + .durationSeconds(profile.getDurationSeconds()) + .roleArn(profile.getRoleArn()) + .roleSessionName(profile.getRoleSessionName()) + .stsRegionId(profile.getStsRegionId()) + .enableVpc(profile.getEnableVpc()) + .policy(profile.getPolicy()) + .externalId(profile.getExternalId()) + .build(); + case "EcsRamRole": + return EcsRamRoleCredentialProvider.builder() + .roleName(profile.getRamRoleName()) + .build(); + case "OIDC": + return OIDCRoleArnCredentialProvider.builder() + .durationSeconds(profile.getDurationSeconds()) + .roleArn(profile.getRoleArn()) + .roleSessionName(profile.getRoleSessionName()) + .oidcProviderArn(profile.getOidcProviderArn()) + .oidcTokenFilePath(profile.getOidcTokenFile()) + .stsRegionId(profile.getStsRegionId()) + .enableVpc(profile.getEnableVpc()) + .policy(profile.getPolicy()) + .build(); + case "ChainableRamRoleArn": + AlibabaCloudCredentialsProvider previousProvider = reloadCredentialsProvider(config, profile.getSourceProfile()); + return RamRoleArnCredentialProvider.builder() + .credentialsProvider(previousProvider) + .durationSeconds(profile.getDurationSeconds()) + .roleArn(profile.getRoleArn()) + .roleSessionName(profile.getRoleSessionName()) + .stsRegionId(profile.getStsRegionId()) + .enableVpc(profile.getEnableVpc()) + .policy(profile.getPolicy()) + .externalId(profile.getExternalId()) + .build(); + default: + throw new CredentialException(String.format("Unsupported profile mode '%s' form CLI credentials file.", profile.getMode())); + } + } + } + } + throw new CredentialException(String.format("Unable to get profile with '%s' form CLI credentials file.", currentProfileName)); + } + + Config parseProfile(String configFilePath) { + File configFile = new File(configFilePath); + if (!configFile.exists() || !configFile.isFile() || !configFile.canRead()) { + throw new CredentialException(String.format("Unable to open credentials file: %s.", configFile.getAbsolutePath())); + } + Gson gson = new Gson(); + try (BufferedReader br = new BufferedReader(new FileReader(configFile))) { + StringBuilder sb = new StringBuilder(); + String line; + while ((line = br.readLine()) != null) { + sb.append(line); + } + String jsonContent = sb.toString(); + return gson.fromJson(jsonContent, Config.class); + } catch (Exception e) { + throw new CredentialException(String.format("Failed to parse credential form CLI credentials file: %s.", configFile.getAbsolutePath())); + } + } + + boolean shouldReloadCredentialsProvider(String profileName) { + return this.credentialsProvider == null || (!StringUtils.isEmpty(this.currentProfileName) && !StringUtils.isEmpty(profileName) && !this.currentProfileName.equals(profileName)); + } + + String getProfileName() { + return this.currentProfileName; + } + + @Override + public String getProviderName() { + return ProviderName.CLI_PROFILE; + } + + @Override + public void close() { + } + + static final class Builder { + private String profileName; + + public Builder profileName(String profileName) { + this.profileName = profileName; + return this; + } + + CLIProfileCredentialsProvider build() { + return new CLIProfileCredentialsProvider(this); + } + } + + static class Config { + @SerializedName("current") + private String current; + @SerializedName("profiles") + private List profiles; + + public String getCurrent() { + return current; + } + + public List getProfiles() { + return profiles; + } + } + + static class Profile { + @SerializedName("name") + private String name; + @SerializedName("mode") + private String mode; + @SerializedName("access_key_id") + private String accessKeyId; + @SerializedName("access_key_secret") + private String accessKeySecret; + @SerializedName("ram_role_arn") + private String roleArn; + @SerializedName("ram_session_name") + private String roleSessionName; + @SerializedName("expired_seconds") + private Integer durationSeconds; + @SerializedName("sts_region") + private String stsRegionId; + @SerializedName("enable_vpc") + private Boolean enableVpc; + @SerializedName("ram_role_name") + private String ramRoleName; + @SerializedName("oidc_token_file") + private String oidcTokenFile; + @SerializedName("oidc_provider_arn") + private String oidcProviderArn; + @SerializedName("source_profile") + private String sourceProfile; + @SerializedName("policy") + private String policy; + @SerializedName("external_id") + private String externalId; + + public String getName() { + return name; + } + + public String getMode() { + return mode; + } + + public String getAccessKeyId() { + return accessKeyId; + } + + public String getAccessKeySecret() { + return accessKeySecret; + } + + public String getRoleArn() { + return roleArn; + } + + public String getRoleSessionName() { + return roleSessionName; + } + + public Integer getDurationSeconds() { + return durationSeconds; + } + + public String getStsRegionId() { + return stsRegionId; + } + + public Boolean getEnableVpc() { + return enableVpc; + } + + public String getRamRoleName() { + return ramRoleName; + } + + public String getOidcTokenFile() { + return oidcTokenFile; + } + + public String getOidcProviderArn() { + return oidcProviderArn; + } + + public String getSourceProfile() { + return sourceProfile; + } + + public String getPolicy() { + return policy; + } + + public String getExternalId() { + return externalId; + } + } +} diff --git a/src/main/java/com/aliyun/credentials/provider/DefaultCredentialsProvider.java b/src/main/java/com/aliyun/credentials/provider/DefaultCredentialsProvider.java index fb27cb1..4cc27c9 100644 --- a/src/main/java/com/aliyun/credentials/provider/DefaultCredentialsProvider.java +++ b/src/main/java/com/aliyun/credentials/provider/DefaultCredentialsProvider.java @@ -2,16 +2,10 @@ import com.aliyun.credentials.exception.CredentialException; import com.aliyun.credentials.models.CredentialModel; -import com.aliyun.credentials.utils.AuthConstant; import com.aliyun.credentials.utils.AuthUtils; +import com.aliyun.credentials.utils.ProviderName; import com.aliyun.credentials.utils.StringUtils; -import com.aliyun.tea.utils.Validate; -import com.google.gson.Gson; -import com.google.gson.annotations.SerializedName; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; import java.util.ArrayList; import java.util.List; import java.util.Vector; @@ -44,11 +38,8 @@ private void createDefaultChain() { } defaultProviders.add(CLIProfileCredentialsProvider.builder().build()); defaultProviders.add(new ProfileCredentialsProvider()); - String roleName = AuthUtils.getEnvironmentECSMetaData(); - if (null != roleName) { - defaultProviders.add(EcsRamRoleCredentialProvider.builder() - .roleName(roleName) - .build()); + if (!AuthUtils.isDisableECSMetaData()) { + defaultProviders.add(EcsRamRoleCredentialProvider.builder().build()); } String uri = AuthUtils.getEnvironmentCredentialsURI(); if (!StringUtils.isEmpty(uri)) { @@ -74,8 +65,17 @@ public CredentialModel getCredentials() { for (AlibabaCloudCredentialsProvider provider : USER_CONFIGURATION_PROVIDERS) { try { credential = provider.getCredentials(); - this.lastUsedCredentialsProvider = provider; - return credential; + if (credential != null) { + this.lastUsedCredentialsProvider = provider; + return CredentialModel.builder() + .accessKeyId(credential.getAccessKeyId()) + .accessKeySecret(credential.getAccessKeySecret()) + .securityToken(credential.getSecurityToken()) + .expiration(credential.getExpiration()) + .type(credential.getType()) + .providerName(String.format("%s/%s", this.getProviderName(), credential.getProviderName())) + .build(); + } } catch (Exception e) { errorMessages.add(provider.getClass().getName() + ": " + e.getMessage()); } @@ -84,8 +84,17 @@ public CredentialModel getCredentials() { for (AlibabaCloudCredentialsProvider provider : defaultProviders) { try { credential = provider.getCredentials(); - this.lastUsedCredentialsProvider = provider; - return credential; + if (credential != null) { + this.lastUsedCredentialsProvider = provider; + return CredentialModel.builder() + .accessKeyId(credential.getAccessKeyId()) + .accessKeySecret(credential.getAccessKeySecret()) + .securityToken(credential.getSecurityToken()) + .expiration(credential.getExpiration()) + .type(credential.getType()) + .providerName(String.format("%s/%s", this.getProviderName(), credential.getProviderName())) + .build(); + } } catch (Exception e) { errorMessages.add(provider.getClass().getSimpleName() + ": " + e.getMessage()); } @@ -113,6 +122,15 @@ public static void clearCredentialsProvider() { DefaultCredentialsProvider.USER_CONFIGURATION_PROVIDERS.clear(); } + @Override + public String getProviderName() { + return ProviderName.DEFAULT; + } + + @Override + public void close() { + } + public static final class Builder { private Boolean reuseLastProviderEnabled = true; @@ -127,238 +145,3 @@ DefaultCredentialsProvider build() { } } - -/** - * CLIProfileCredentialsProvider is not public. - */ -class CLIProfileCredentialsProvider implements AlibabaCloudCredentialsProvider { - private final String CLI_CREDENTIALS_CONFIG_PATH = System.getProperty("user.home") + - "/.aliyun/config.json"; - private volatile AlibabaCloudCredentialsProvider credentialsProvider; - private volatile String currentProfileName; - private final Object credentialsProviderLock = new Object(); - - private CLIProfileCredentialsProvider(Builder builder) { - this.currentProfileName = builder.profileName; - } - - static Builder builder() { - return new Builder(); - } - - @Override - public CredentialModel getCredentials() { - if (AuthUtils.isDisableCLIProfile()) { - throw new CredentialException("CLI credentials file is disabled."); - } - Config config = parseProfile(CLI_CREDENTIALS_CONFIG_PATH); - if (null == config) { - throw new CredentialException("Unable to get profile from empty CLI credentials file."); - } - String refreshedProfileName = System.getenv("ALIBABA_CLOUD_PROFILE"); - if (shouldReloadCredentialsProvider(refreshedProfileName)) { - synchronized (credentialsProviderLock) { - if (shouldReloadCredentialsProvider(refreshedProfileName)) { - if (!StringUtils.isEmpty(refreshedProfileName)) { - this.currentProfileName = refreshedProfileName; - } - this.credentialsProvider = reloadCredentialsProvider(config, this.currentProfileName); - } - } - } - return this.credentialsProvider.getCredentials(); - } - - AlibabaCloudCredentialsProvider reloadCredentialsProvider(Config config, String profileName) { - String currentProfileName = !StringUtils.isEmpty(profileName) ? profileName : config.getCurrent(); - List profiles = config.getProfiles(); - if (profiles != null && !profiles.isEmpty()) { - for (Profile profile : profiles) { - if (!StringUtils.isEmpty(profile.getName()) && profile.getName().equals(currentProfileName)) { - switch (profile.getMode()) { - case "AK": - return StaticCredentialsProvider.builder() - .credential(CredentialModel.builder() - .accessKeyId(Validate.notNull( - profile.getAccessKeyId(), "AccessKeyId must not be null.")) - .accessKeySecret(Validate.notNull( - profile.getAccessKeySecret(), "AccessKeySecret must not be null.")) - .type(AuthConstant.ACCESS_KEY) - .build()) - .build(); - case "RamRoleArn": - AlibabaCloudCredentialsProvider innerProvider = StaticCredentialsProvider.builder() - .credential(CredentialModel.builder() - .accessKeyId(Validate.notNull( - profile.getAccessKeyId(), "AccessKeyId must not be null.")) - .accessKeySecret(Validate.notNull( - profile.getAccessKeySecret(), "AccessKeySecret must not be null.")) - .type(AuthConstant.ACCESS_KEY) - .build()) - .build(); - ; - return RamRoleArnCredentialProvider.builder() - .credentialsProvider(innerProvider) - .durationSeconds(profile.getDurationSeconds() != null ? profile.getDurationSeconds() : 3600) - .roleArn(profile.getRoleArn()) - .roleSessionName(profile.getRoleSessionName()) - .build(); - case "EcsRamRole": - return EcsRamRoleCredentialProvider.builder() - .roleName(profile.getRamRoleName()) - .build(); - case "OIDC": - return OIDCRoleArnCredentialProvider.builder() - .durationSeconds(profile.getDurationSeconds() != null ? profile.getDurationSeconds() : 3600) - .roleArn(profile.getRoleArn()) - .roleSessionName(profile.getRoleSessionName()) - .oidcProviderArn(profile.getOidcProviderArn()) - .oidcTokenFilePath(profile.getOidcTokenFile()) - .build(); - case "ChainableRamRoleArn": - AlibabaCloudCredentialsProvider previousProvider = reloadCredentialsProvider(config, profile.getSourceProfile()); - return RamRoleArnCredentialProvider.builder() - .credentialsProvider(previousProvider) - .durationSeconds(profile.getDurationSeconds() != null ? profile.getDurationSeconds() : 3600) - .roleArn(profile.getRoleArn()) - .roleSessionName(profile.getRoleSessionName()) - .build(); - default: - throw new CredentialException(String.format("Unsupported profile mode '%s' form CLI credentials file.", profile.getMode())); - } - } - } - } - throw new CredentialException(String.format("Unable to get profile with '%s' form CLI credentials file.", currentProfileName)); - } - - Config parseProfile(String configFilePath) { - File configFile = new File(configFilePath); - if (!configFile.exists() || !configFile.isFile() || !configFile.canRead()) { - throw new CredentialException(String.format("Unable to open credentials file: %s.", configFile.getAbsolutePath())); - } - Gson gson = new Gson(); - try (BufferedReader br = new BufferedReader(new FileReader(configFile))) { - StringBuilder sb = new StringBuilder(); - String line; - while ((line = br.readLine()) != null) { - sb.append(line); - } - String jsonContent = sb.toString(); - return gson.fromJson(jsonContent, Config.class); - } catch (Exception e) { - throw new CredentialException(String.format("Failed to parse credential form CLI credentials file: %s.", configFile.getAbsolutePath())); - } - } - - boolean shouldReloadCredentialsProvider(String profileName) { - return this.credentialsProvider == null || (!StringUtils.isEmpty(this.currentProfileName) && !StringUtils.isEmpty(profileName) && !this.currentProfileName.equals(profileName)); - } - - String getProfileName() { - return this.currentProfileName; - } - - static final class Builder { - private String profileName = System.getenv("ALIBABA_CLOUD_PROFILE"); - - public Builder profileName(String profileName) { - this.profileName = profileName; - return this; - } - - CLIProfileCredentialsProvider build() { - return new CLIProfileCredentialsProvider(this); - } - } - - static class Config { - @SerializedName("current") - private String current; - @SerializedName("profiles") - private List profiles; - - public String getCurrent() { - return current; - } - - public List getProfiles() { - return profiles; - } - } - - static class Profile { - @SerializedName("name") - private String name; - @SerializedName("mode") - private String mode; - @SerializedName("access_key_id") - private String accessKeyId; - @SerializedName("access_key_secret") - private String accessKeySecret; - @SerializedName("ram_role_arn") - private String roleArn; - @SerializedName("ram_session_name") - private String roleSessionName; - @SerializedName("expired_seconds") - private Integer durationSeconds; - @SerializedName("sts_region") - private String stsRegionId; - @SerializedName("ram_role_name") - private String ramRoleName; - @SerializedName("oidc_token_file") - private String oidcTokenFile; - @SerializedName("oidc_provider_arn") - private String oidcProviderArn; - @SerializedName("source_profile") - private String sourceProfile; - - public String getName() { - return name; - } - - public String getMode() { - return mode; - } - - public String getAccessKeyId() { - return accessKeyId; - } - - public String getAccessKeySecret() { - return accessKeySecret; - } - - public String getRoleArn() { - return roleArn; - } - - public String getRoleSessionName() { - return roleSessionName; - } - - public Integer getDurationSeconds() { - return durationSeconds; - } - - public String getStsRegionId() { - return stsRegionId; - } - - public String getRamRoleName() { - return ramRoleName; - } - - public String getOidcTokenFile() { - return oidcTokenFile; - } - - public String getOidcProviderArn() { - return oidcProviderArn; - } - - public String getSourceProfile() { - return sourceProfile; - } - } -} diff --git a/src/main/java/com/aliyun/credentials/provider/ECSMetadataServiceCredentialsFetcher.java b/src/main/java/com/aliyun/credentials/provider/ECSMetadataServiceCredentialsFetcher.java index 3ce5265..e80d53b 100644 --- a/src/main/java/com/aliyun/credentials/provider/ECSMetadataServiceCredentialsFetcher.java +++ b/src/main/java/com/aliyun/credentials/provider/ECSMetadataServiceCredentialsFetcher.java @@ -8,6 +8,8 @@ import com.aliyun.credentials.models.CredentialModel; import com.aliyun.credentials.utils.AuthConstant; import com.aliyun.credentials.utils.ParameterHelper; +import com.aliyun.credentials.utils.ProviderName; +import com.aliyun.credentials.utils.StringUtils; import com.google.gson.Gson; import java.net.MalformedURLException; @@ -26,39 +28,27 @@ public class ECSMetadataServiceCredentialsFetcher { private final boolean disableIMDSv1; private final int metadataTokenDuration = 21600; - public ECSMetadataServiceCredentialsFetcher(String roleName, int connectionTimeout, int readTimeout) { - if (connectionTimeout > 1000) { - this.connectionTimeout = connectionTimeout; - } - if (readTimeout > 1000) { - this.readTimeout = readTimeout; - } + public ECSMetadataServiceCredentialsFetcher(String roleName, Integer connectionTimeout, Integer readTimeout) { + this.connectionTimeout = connectionTimeout == null ? 1000 : connectionTimeout; + this.readTimeout = readTimeout == null ? 1000 : readTimeout; this.disableIMDSv1 = false; this.roleName = roleName; setCredentialUrl(); } @Deprecated - public ECSMetadataServiceCredentialsFetcher(String roleName, boolean disableIMDSv1, int metadataTokenDuration, int connectionTimeout, int readTimeout) { - if (connectionTimeout > 1000) { - this.connectionTimeout = connectionTimeout; - } - if (readTimeout > 1000) { - this.readTimeout = readTimeout; - } + public ECSMetadataServiceCredentialsFetcher(String roleName, Boolean disableIMDSv1, Integer metadataTokenDuration, Integer connectionTimeout, Integer readTimeout) { + this.connectionTimeout = connectionTimeout == null ? 1000 : connectionTimeout; + this.readTimeout = readTimeout == null ? 1000 : readTimeout; this.disableIMDSv1 = disableIMDSv1; this.roleName = roleName; setCredentialUrl(); } - public ECSMetadataServiceCredentialsFetcher(String roleName, boolean disableIMDSv1, int connectionTimeout, int readTimeout) { - if (connectionTimeout > 1000) { - this.connectionTimeout = connectionTimeout; - } - if (readTimeout > 1000) { - this.readTimeout = readTimeout; - } - this.disableIMDSv1 = disableIMDSv1; + public ECSMetadataServiceCredentialsFetcher(String roleName, Boolean disableIMDSv1, Integer connectionTimeout, Integer readTimeout) { + this.connectionTimeout = connectionTimeout == null ? 1000 : connectionTimeout; + this.readTimeout = readTimeout == null ? 1000 : readTimeout; + this.disableIMDSv1 = disableIMDSv1 == null ? false : disableIMDSv1; this.roleName = roleName; setCredentialUrl(); } @@ -83,7 +73,11 @@ public String fetchRoleName(CompatibleUrlConnClient client) { } public String getMetadata(CompatibleUrlConnClient client) { - HttpRequest request = new HttpRequest(credentialUrl.toString()); + return getMetadata(client, credentialUrl.toString()); + } + + private String getMetadata(CompatibleUrlConnClient client, String url) { + HttpRequest request = new HttpRequest(url); request.setSysMethod(MethodType.GET); request.setSysConnectTimeout(connectionTimeout); request.setSysReadTimeout(readTimeout); @@ -97,8 +91,6 @@ public String getMetadata(CompatibleUrlConnClient client) { response = client.syncInvoke(request); } catch (Exception e) { throw new CredentialException("Failed to connect ECS Metadata Service: " + e); - } finally { - client.close(); } if (response.getResponseCode() == 404) { @@ -113,7 +105,11 @@ public String getMetadata(CompatibleUrlConnClient client) { } public RefreshResult fetch(CompatibleUrlConnClient client) { - String jsonContent = getMetadata(client); + String roleName = this.roleName; + if (StringUtils.isEmpty(this.roleName)) { + roleName = getMetadata(client, "http://" + metadataServiceHost + URL_IN_ECS_METADATA); + } + String jsonContent = getMetadata(client, "http://" + metadataServiceHost + URL_IN_ECS_METADATA + roleName); Map result = new Gson().fromJson(jsonContent, Map.class); if (!"Success".equals(result.get("Code"))) { @@ -125,6 +121,7 @@ public RefreshResult fetch(CompatibleUrlConnClient client) { .accessKeySecret(result.get("AccessKeySecret")) .securityToken(result.get("SecurityToken")) .type(AuthConstant.ECS_RAM_ROLE) + .providerName(ProviderName.ECS_RAM_ROLE) .expiration(expiration) .build(); return RefreshResult.builder(credential) @@ -180,7 +177,7 @@ private String getMetadataToken(CompatibleUrlConnClient client) { } private String throwErrorOrReturn(Exception e) { - if (getDisableIMDSv1()) { + if (this.disableIMDSv1) { throw new CredentialException("Failed to get token from ECS Metadata Service, and fallback to IMDS v1 is disabled via the disableIMDSv1 configuration is turned on. Original error: " + e.getMessage()); } return null; diff --git a/src/main/java/com/aliyun/credentials/provider/EcsRamRoleCredentialProvider.java b/src/main/java/com/aliyun/credentials/provider/EcsRamRoleCredentialProvider.java index 3d4a874..a663785 100644 --- a/src/main/java/com/aliyun/credentials/provider/EcsRamRoleCredentialProvider.java +++ b/src/main/java/com/aliyun/credentials/provider/EcsRamRoleCredentialProvider.java @@ -1,10 +1,12 @@ package com.aliyun.credentials.provider; import com.aliyun.credentials.Configuration; +import com.aliyun.credentials.exception.CredentialException; import com.aliyun.credentials.http.CompatibleUrlConnClient; import com.aliyun.credentials.models.Config; import com.aliyun.credentials.models.CredentialModel; import com.aliyun.credentials.utils.AuthUtils; +import com.aliyun.credentials.utils.ProviderName; import com.aliyun.credentials.utils.StringUtils; public class EcsRamRoleCredentialProvider extends SessionCredentialsProvider { @@ -15,8 +17,9 @@ public class EcsRamRoleCredentialProvider extends SessionCredentialsProvider { public EcsRamRoleCredentialProvider(String roleName) { super(new BuilderImpl()); if (StringUtils.isEmpty(roleName)) { - CompatibleUrlConnClient client = new CompatibleUrlConnClient(); - roleName = new ECSMetadataServiceCredentialsFetcher("").fetchRoleName(client); + try (CompatibleUrlConnClient client = new CompatibleUrlConnClient()) { + roleName = new ECSMetadataServiceCredentialsFetcher("").fetchRoleName(client); + } } this.fetcher = new ECSMetadataServiceCredentialsFetcher(roleName); } @@ -25,9 +28,10 @@ public EcsRamRoleCredentialProvider(String roleName) { public EcsRamRoleCredentialProvider(Configuration config) { super(new BuilderImpl()); if (StringUtils.isEmpty(config.getRoleName())) { - CompatibleUrlConnClient client = new CompatibleUrlConnClient(); - String roleName = new ECSMetadataServiceCredentialsFetcher("").fetchRoleName(client); - config.setRoleName(roleName); + try (CompatibleUrlConnClient client = new CompatibleUrlConnClient()) { + String roleName = new ECSMetadataServiceCredentialsFetcher("").fetchRoleName(client); + config.setRoleName(roleName); + } } this.fetcher = new ECSMetadataServiceCredentialsFetcher(config.getRoleName(), config.getConnectTimeout(), config.getReadTimeout()); } @@ -37,13 +41,15 @@ public EcsRamRoleCredentialProvider(Config config) { super(new BuilderImpl()); String roleName = config.roleName; if (StringUtils.isEmpty(roleName)) { - CompatibleUrlConnClient client = new CompatibleUrlConnClient(); - roleName = new ECSMetadataServiceCredentialsFetcher( - "", - config.disableIMDSv1, - config.connectTimeout, - config.timeout - ).fetchRoleName(client); + try (CompatibleUrlConnClient client = new CompatibleUrlConnClient()) { + roleName = new ECSMetadataServiceCredentialsFetcher( + "", + config.disableIMDSv1, + config.connectTimeout, + config.timeout + ).fetchRoleName(client); + } + } this.fetcher = new ECSMetadataServiceCredentialsFetcher( roleName, @@ -54,19 +60,14 @@ public EcsRamRoleCredentialProvider(Config config) { private EcsRamRoleCredentialProvider(BuilderImpl builder) { super(builder); - String roleName = builder.roleName; - if (StringUtils.isEmpty(roleName)) { - CompatibleUrlConnClient client = new CompatibleUrlConnClient(); - roleName = new ECSMetadataServiceCredentialsFetcher( - "", - builder.disableIMDSv1, - builder.connectionTimeout, - builder.readTimeout - ).fetchRoleName(client); + if (AuthUtils.isDisableECSMetaData()) { + throw new CredentialException("IMDS credentials is disabled."); } + String roleName = builder.roleName == null ? AuthUtils.getEnvironmentECSMetaData() : builder.roleName; + boolean disableIMDSv1 = builder.disableIMDSv1 == null ? AuthUtils.getDisableECSIMDSv1() : builder.disableIMDSv1; this.fetcher = new ECSMetadataServiceCredentialsFetcher( roleName, - builder.disableIMDSv1, + disableIMDSv1, builder.connectionTimeout, builder.readTimeout); } @@ -77,8 +78,9 @@ public static Builder builder() { @Override public RefreshResult refreshCredentials() { - CompatibleUrlConnClient client = new CompatibleUrlConnClient(); - return fetcher.fetch(client); + try (CompatibleUrlConnClient client = new CompatibleUrlConnClient()) { + return fetcher.fetch(client); + } } public ECSMetadataServiceCredentialsFetcher getFetcher() { @@ -89,10 +91,19 @@ public void setFetcher(ECSMetadataServiceCredentialsFetcher fetcher) { this.fetcher = fetcher; } + @Override + public String getProviderName() { + return ProviderName.ECS_RAM_ROLE; + } + + @Override + public void close() { + } + public interface Builder extends SessionCredentialsProvider.Builder { Builder roleName(String roleName); - Builder disableIMDSv1(boolean disableIMDSv1); + Builder disableIMDSv1(Boolean disableIMDSv1); @Deprecated Builder enableIMDSv2(boolean enableIMDSv2); @@ -100,9 +111,9 @@ public interface Builder extends SessionCredentialsProvider.Builder implements Builder { private String roleName; - private boolean disableIMDSv1 = AuthUtils.getDisableECSIMDSv1(); - private boolean enableIMDSv2 = AuthUtils.getEnableECSIMDSv2(); - private int metadataTokenDuration = 21600; - private int connectionTimeout = 1000; - private int readTimeout = 1000; + private Boolean disableIMDSv1; + private boolean enableIMDSv2; + private int metadataTokenDuration; + private Integer connectionTimeout; + private Integer readTimeout; public Builder roleName(String roleName) { this.roleName = roleName; return this; } - public Builder disableIMDSv1(boolean disableIMDSv1) { + public Builder disableIMDSv1(Boolean disableIMDSv1) { this.disableIMDSv1 = disableIMDSv1; return this; } @@ -140,12 +151,12 @@ public Builder metadataTokenDuration(int metadataTokenDuration) { return this; } - public Builder connectionTimeout(int connectionTimeout) { + public Builder connectionTimeout(Integer connectionTimeout) { this.connectionTimeout = connectionTimeout; return this; } - public Builder readTimeout(int readTimeout) { + public Builder readTimeout(Integer readTimeout) { this.readTimeout = readTimeout; return this; } diff --git a/src/main/java/com/aliyun/credentials/provider/EnvironmentVariableCredentialsProvider.java b/src/main/java/com/aliyun/credentials/provider/EnvironmentVariableCredentialsProvider.java index 221e136..45d44e3 100644 --- a/src/main/java/com/aliyun/credentials/provider/EnvironmentVariableCredentialsProvider.java +++ b/src/main/java/com/aliyun/credentials/provider/EnvironmentVariableCredentialsProvider.java @@ -4,6 +4,7 @@ import com.aliyun.credentials.models.CredentialModel; import com.aliyun.credentials.utils.AuthConstant; import com.aliyun.credentials.utils.AuthUtils; +import com.aliyun.credentials.utils.ProviderName; import com.aliyun.credentials.utils.StringUtils; public class EnvironmentVariableCredentialsProvider implements AlibabaCloudCredentialsProvider { @@ -24,12 +25,23 @@ public CredentialModel getCredentials() { .accessKeySecret(accessKeySecret) .securityToken(securityToken) .type(AuthConstant.STS) + .providerName(this.getProviderName()) .build(); } return CredentialModel.builder() .accessKeyId(accessKeyId) .accessKeySecret(accessKeySecret) .type(AuthConstant.ACCESS_KEY) + .providerName(this.getProviderName()) .build(); } + + @Override + public String getProviderName() { + return ProviderName.ENV; + } + + @Override + public void close() { + } } diff --git a/src/main/java/com/aliyun/credentials/provider/OIDCRoleArnCredentialProvider.java b/src/main/java/com/aliyun/credentials/provider/OIDCRoleArnCredentialProvider.java index ba5be9f..78a189c 100644 --- a/src/main/java/com/aliyun/credentials/provider/OIDCRoleArnCredentialProvider.java +++ b/src/main/java/com/aliyun/credentials/provider/OIDCRoleArnCredentialProvider.java @@ -5,10 +5,7 @@ import com.aliyun.credentials.http.*; import com.aliyun.credentials.models.Config; import com.aliyun.credentials.models.CredentialModel; -import com.aliyun.credentials.utils.AuthConstant; -import com.aliyun.credentials.utils.AuthUtils; -import com.aliyun.credentials.utils.ParameterHelper; -import com.aliyun.credentials.utils.StringUtils; +import com.aliyun.credentials.utils.*; import com.aliyun.tea.utils.Validate; import com.google.gson.Gson; @@ -35,7 +32,7 @@ public class OIDCRoleArnCredentialProvider extends SessionCredentialsProvider { /** * An identifier for the assumed role session. */ - private String roleSessionName = "defaultSessionName"; + private String roleSessionName = "javaSdkRoleSessionName"; private String regionId = "cn-hangzhou"; private String policy; @@ -43,8 +40,8 @@ public class OIDCRoleArnCredentialProvider extends SessionCredentialsProvider { /** * Unit of millisecond */ - private int connectTimeout = 1000; - private int readTimeout = 1000; + private int connectTimeout = 10000; + private int readTimeout = 5000; /** * Endpoint of RAM OpenAPI @@ -124,16 +121,45 @@ public OIDCRoleArnCredentialProvider(String roleSessionName, String roleArn, private OIDCRoleArnCredentialProvider(BuilderImpl builder) { super(builder); - this.roleSessionName = builder.roleSessionName; - this.durationSeconds = builder.durationSeconds; - this.roleArn = Validate.notNull(builder.roleArn, "RoleArn or environment variable ALIBABA_CLOUD_ROLE_ARN cannot be null."); - this.oidcProviderArn = Validate.notNull(builder.oidcProviderArn, "OIDCProviderArn or environment variable ALIBABA_CLOUD_OIDC_PROVIDER_ARN cannot be null."); - this.oidcTokenFilePath = Validate.notNull(builder.oidcTokenFilePath, "OIDCTokenFilePath or environment variable ALIBABA_CLOUD_OIDC_TOKEN_FILE cannot be null."); + this.roleSessionName = builder.roleSessionName == null ? !StringUtils.isEmpty(AuthUtils.getEnvironmentRoleSessionName()) ? + AuthUtils.getEnvironmentRoleSessionName() : "credentials-java-" + 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.regionId = builder.regionId; this.policy = builder.policy; - this.connectTimeout = builder.connectionTimeout; - this.readTimeout = builder.readTimeout; - this.STSEndpoint = builder.STSEndpoint; + this.connectTimeout = 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"; + } + } } public static Builder builder() { @@ -142,8 +168,9 @@ public static Builder builder() { @Override public RefreshResult refreshCredentials() { - CompatibleUrlConnClient client = new CompatibleUrlConnClient(); - return createCredential(client); + try (CompatibleUrlConnClient client = new CompatibleUrlConnClient()) { + return createCredential(client); + } } public RefreshResult createCredential(CompatibleUrlConnClient client) { @@ -207,12 +234,16 @@ public RefreshResult getNewSessionCredentials(CompatibleUrlConn 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())); + } long expiration = ParameterHelper.getUTCDate(result.get("Expiration")).getTime(); CredentialModel credential = CredentialModel.builder() .accessKeyId(result.get("AccessKeyId")) .accessKeySecret(result.get("AccessKeySecret")) .securityToken(result.get("SecurityToken")) .type(AuthConstant.OIDC_ROLE_ARN) + .providerName(this.getProviderName()) .expiration(expiration) .build(); return RefreshResult.builder(credential) @@ -293,10 +324,19 @@ public void setSTSEndpoint(String STSEndpoint) { this.STSEndpoint = STSEndpoint; } + @Override + public String getProviderName() { + return ProviderName.OIDC_ROLE_ARN; + } + + @Override + public void close() { + } + public interface Builder extends SessionCredentialsProvider.Builder { Builder roleSessionName(String roleSessionName); - Builder durationSeconds(int durationSeconds); + Builder durationSeconds(Integer durationSeconds); Builder roleArn(String roleArn); @@ -308,12 +348,16 @@ public interface Builder extends SessionCredentialsProvider.Builder implements Builder { - private String roleSessionName = StringUtils.isEmpty(System.getenv("ALIBABA_CLOUD_ROLE_SESSION_NAME")) ? - "defaultSessionName" - : System.getenv("ALIBABA_CLOUD_ROLE_SESSION_NAME"); - private int durationSeconds = 3600; - private String roleArn = System.getenv("ALIBABA_CLOUD_ROLE_ARN"); - private String oidcProviderArn = System.getenv("ALIBABA_CLOUD_OIDC_PROVIDER_ARN"); - private String oidcTokenFilePath = System.getenv("ALIBABA_CLOUD_OIDC_TOKEN_FILE"); - private String regionId = "cn-hangzhou"; + private String roleSessionName; + private Integer durationSeconds; + private String roleArn; + private String oidcProviderArn; + private String oidcTokenFilePath; + private String regionId; private String policy; - private int connectionTimeout = 1000; - private int readTimeout = 1000; - private String STSEndpoint = "sts.aliyuncs.com"; + private Integer connectionTimeout; + private Integer readTimeout; + private String STSEndpoint; + private String stsRegionId; + private Boolean enableVpc; public Builder roleSessionName(String roleSessionName) { if (!StringUtils.isEmpty(roleSessionName)) { @@ -341,7 +385,7 @@ public Builder roleSessionName(String roleSessionName) { return this; } - public Builder durationSeconds(int durationSeconds) { + public Builder durationSeconds(Integer durationSeconds) { this.durationSeconds = durationSeconds; return this; } @@ -379,12 +423,12 @@ public Builder policy(String policy) { return this; } - public Builder connectionTimeout(int connectionTimeout) { + public Builder connectionTimeout(Integer connectionTimeout) { this.connectionTimeout = connectionTimeout; return this; } - public Builder readTimeout(int readTimeout) { + public Builder readTimeout(Integer readTimeout) { this.readTimeout = readTimeout; return this; } @@ -394,6 +438,16 @@ public Builder STSEndpoint(String 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); diff --git a/src/main/java/com/aliyun/credentials/provider/ProfileCredentialsProvider.java b/src/main/java/com/aliyun/credentials/provider/ProfileCredentialsProvider.java index 526fb3f..0055b28 100644 --- a/src/main/java/com/aliyun/credentials/provider/ProfileCredentialsProvider.java +++ b/src/main/java/com/aliyun/credentials/provider/ProfileCredentialsProvider.java @@ -2,10 +2,7 @@ import com.aliyun.credentials.exception.CredentialException; import com.aliyun.credentials.models.CredentialModel; -import com.aliyun.credentials.utils.ProfileUtils; -import com.aliyun.credentials.utils.AuthConstant; -import com.aliyun.credentials.utils.AuthUtils; -import com.aliyun.credentials.utils.StringUtils; +import com.aliyun.credentials.utils.*; import java.io.IOException; import java.util.HashMap; @@ -82,12 +79,13 @@ private CredentialModel createCredential(Map clientConfig, String accessKeyId = clientConfig.get(AuthConstant.INI_ACCESS_KEY_ID); String accessKeySecret = clientConfig.get(AuthConstant.INI_ACCESS_KEY_IDSECRET); if (StringUtils.isEmpty(accessKeyId) || StringUtils.isEmpty(accessKeySecret)) { - return null; + throw new CredentialException("The configured access_key_id or access_key_secret is empty."); } return CredentialModel.builder() .accessKeyId(accessKeyId) .accessKeySecret(accessKeySecret) .type(AuthConstant.ACCESS_KEY) + .providerName(String.format("%s/%s", this.getProviderName(), ProviderName.STATIC_AK)) .build(); } @@ -114,7 +112,14 @@ private CredentialModel getSTSAssumeRoleSessionCredentials(Map c .regionId(regionId) .policy(policy) .build()); - return provider.getCredentials(); + CredentialModel credential = provider.getCredentials(); + return CredentialModel.builder() + .accessKeyId(credential.getAccessKeyId()) + .accessKeySecret(credential.getAccessKeySecret()) + .securityToken(credential.getSecurityToken()) + .type(credential.getType()) + .providerName(String.format("%s/%s", this.getProviderName(), credential.getProviderName())) + .build(); } private CredentialModel getSTSOIDCRoleSessionCredentials(Map clientConfig, @@ -140,7 +145,14 @@ private CredentialModel getSTSOIDCRoleSessionCredentials(Map cli .regionId(regionId) .policy(policy) .build()); - return provider.getCredentials(); + CredentialModel credential = provider.getCredentials(); + return CredentialModel.builder() + .accessKeyId(credential.getAccessKeyId()) + .accessKeySecret(credential.getAccessKeySecret()) + .securityToken(credential.getSecurityToken()) + .type(credential.getType()) + .providerName(String.format("%s/%s", this.getProviderName(), credential.getProviderName())) + .build(); } private CredentialModel getSTSGetSessionAccessKeyCredentials(Map clientConfig, @@ -159,7 +171,14 @@ private CredentialModel getSTSGetSessionAccessKeyCredentials(Map .publicKeyId(publicKeyId) .privateKeyFile(privateKey) .build()); - return provider.getCredentials(); + CredentialModel credential = provider.getCredentials(); + return CredentialModel.builder() + .accessKeyId(credential.getAccessKeyId()) + .accessKeySecret(credential.getAccessKeySecret()) + .securityToken(credential.getSecurityToken()) + .type(credential.getType()) + .providerName(String.format("%s/%s", this.getProviderName(), credential.getProviderName())) + .build(); } private CredentialModel getInstanceProfileCredentials(Map clientConfig, @@ -172,6 +191,22 @@ private CredentialModel getInstanceProfileCredentials(Map client EcsRamRoleCredentialProvider.builder() .roleName(roleName) .build()); - return provider.getCredentials(); + CredentialModel credential = provider.getCredentials(); + return CredentialModel.builder() + .accessKeyId(credential.getAccessKeyId()) + .accessKeySecret(credential.getAccessKeySecret()) + .securityToken(credential.getSecurityToken()) + .type(credential.getType()) + .providerName(String.format("%s/%s", this.getProviderName(), credential.getProviderName())) + .build(); + } + + @Override + public String getProviderName() { + return ProviderName.PROFILE; + } + + @Override + public void close() { } } diff --git a/src/main/java/com/aliyun/credentials/provider/RamRoleArnCredentialProvider.java b/src/main/java/com/aliyun/credentials/provider/RamRoleArnCredentialProvider.java index 76f013b..b3c0c58 100644 --- a/src/main/java/com/aliyun/credentials/provider/RamRoleArnCredentialProvider.java +++ b/src/main/java/com/aliyun/credentials/provider/RamRoleArnCredentialProvider.java @@ -8,9 +8,7 @@ import com.aliyun.credentials.http.MethodType; import com.aliyun.credentials.models.Config; import com.aliyun.credentials.models.CredentialModel; -import com.aliyun.credentials.utils.AuthConstant; -import com.aliyun.credentials.utils.ParameterHelper; -import com.aliyun.credentials.utils.StringUtils; +import com.aliyun.credentials.utils.*; import com.aliyun.tea.utils.Validate; import com.google.gson.Gson; @@ -38,8 +36,8 @@ public class RamRoleArnCredentialProvider extends SessionCredentialsProvider { /** * Unit of millisecond */ - private int connectTimeout = 1000; - private int readTimeout = 1000; + private int connectTimeout = 10000; + private int readTimeout = 5000; /** * Endpoint of RAM OpenAPI @@ -81,6 +79,7 @@ public RamRoleArnCredentialProvider(String accessKeyId, String accessKeySecret, .accessKeyId(accessKeyId) .accessKeySecret(accessKeySecret) .type(AuthConstant.ACCESS_KEY) + .providerName(ProviderName.STATIC_AK) .build()) .build(); } @@ -96,16 +95,52 @@ public RamRoleArnCredentialProvider(String accessKeyId, String accessKeySecret, private RamRoleArnCredentialProvider(BuilderImpl builder) { super(builder); - this.roleSessionName = builder.roleSessionName; - this.durationSeconds = builder.durationSeconds; - this.roleArn = builder.roleArn; + this.roleSessionName = builder.roleSessionName == null ? !StringUtils.isEmpty(AuthUtils.getEnvironmentRoleSessionName()) ? + AuthUtils.getEnvironmentRoleSessionName() : "credentials-java-" + 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.regionId = builder.regionId; this.policy = builder.policy; - this.connectTimeout = builder.connectionTimeout; - this.readTimeout = builder.readTimeout; - this.STSEndpoint = builder.STSEndpoint; + this.externalId = builder.externalId; + this.connectTimeout = 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"; + } + } + if (null != builder.credentialsProvider) { this.credentialsProvider = builder.credentialsProvider; + } else if (null != builder.securityToken) { + this.credentialsProvider = StaticCredentialsProvider.builder() + .credential(CredentialModel.builder() + .accessKeyId(Validate.notNull( + builder.accessKeyId, "AccessKeyId must not be null.")) + .accessKeySecret(Validate.notNull( + builder.accessKeySecret, "AccessKeySecret must not be null.")) + .securityToken(Validate.notNull( + builder.securityToken, "SecurityToken must not be null.")) + .type(AuthConstant.STS) + .providerName(ProviderName.STATIC_STS) + .build()) + .build(); } else { this.credentialsProvider = StaticCredentialsProvider.builder() .credential(CredentialModel.builder() @@ -114,11 +149,10 @@ private RamRoleArnCredentialProvider(BuilderImpl builder) { .accessKeySecret(Validate.notNull( builder.accessKeySecret, "AccessKeySecret must not be null.")) .type(AuthConstant.ACCESS_KEY) + .providerName(ProviderName.STATIC_AK) .build()) .build(); } - - this.externalId = builder.externalId; } public static Builder builder() { @@ -183,12 +217,16 @@ public RefreshResult getNewSessionCredentials(CompatibleUrlConn throw new CredentialException(String.format("Error retrieving credentials from RamRoleArn 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 RamRoleArn result: %s.", httpResponse.getHttpContentString())); + } long expiration = ParameterHelper.getUTCDate(result.get("Expiration")).getTime(); CredentialModel credential = CredentialModel.builder() .accessKeyId(result.get("AccessKeyId")) .accessKeySecret(result.get("AccessKeySecret")) .securityToken(result.get("SecurityToken")) .type(AuthConstant.RAM_ROLE_ARN) + .providerName(String.format("%s/%s", this.getProviderName(), credentials.getProviderName())) .expiration(expiration) .build(); return RefreshResult.builder(credential) @@ -286,10 +324,19 @@ public String getExternalId() { return this.externalId; } + @Override + public String getProviderName() { + return ProviderName.RAM_ROLE_ARN; + } + + @Override + public void close() { + } + public interface Builder extends SessionCredentialsProvider.Builder { Builder roleSessionName(String roleSessionName); - Builder durationSeconds(int durationSeconds); + Builder durationSeconds(Integer durationSeconds); Builder roleArn(String roleArn); @@ -297,16 +344,22 @@ public interface Builder extends SessionCredentialsProvider.Builder implements Builder { - private String roleSessionName = StringUtils.isEmpty(System.getenv("ALIBABA_CLOUD_ROLE_SESSION_NAME")) ? - "javaSdkRoleSessionName" - : System.getenv("ALIBABA_CLOUD_ROLE_SESSION_NAME"); - private int durationSeconds = 3600; - private String roleArn = System.getenv("ALIBABA_CLOUD_ROLE_ARN"); - private String regionId = "cn-hangzhou"; + private String roleSessionName; + private Integer durationSeconds; + private String roleArn; + private String regionId; private String policy; - private int connectionTimeout = 1000; - private int readTimeout = 1000; - private String STSEndpoint = "sts.aliyuncs.com"; + private Integer connectionTimeout; + private Integer readTimeout; + private String STSEndpoint; + private String stsRegionId; + private Boolean enableVpc; private String accessKeyId; private String accessKeySecret; + private String securityToken; private AlibabaCloudCredentialsProvider credentialsProvider; private String externalId; @@ -340,7 +394,7 @@ public Builder roleSessionName(String roleSessionName) { return this; } - public Builder durationSeconds(int durationSeconds) { + public Builder durationSeconds(Integer durationSeconds) { this.durationSeconds = durationSeconds; return this; } @@ -364,12 +418,12 @@ public Builder policy(String policy) { return this; } - public Builder connectionTimeout(int connectionTimeout) { + public Builder connectionTimeout(Integer connectionTimeout) { this.connectionTimeout = connectionTimeout; return this; } - public Builder readTimeout(int readTimeout) { + public Builder readTimeout(Integer readTimeout) { this.readTimeout = readTimeout; return this; } @@ -379,6 +433,16 @@ public Builder STSEndpoint(String STSEndpoint) { return this; } + public Builder stsRegionId(String stsRegionId) { + this.stsRegionId = stsRegionId; + return this; + } + + public Builder enableVpc(Boolean enableVpc) { + this.enableVpc = enableVpc; + return this; + } + public Builder accessKeyId(String accessKeyId) { this.accessKeyId = accessKeyId; return this; @@ -389,6 +453,11 @@ public Builder accessKeySecret(String accessKeySecret) { return this; } + public Builder securityToken(String securityToken) { + this.securityToken = securityToken; + return this; + } + public Builder credentialsProvider(AlibabaCloudCredentialsProvider credentialsProvider) { this.credentialsProvider = credentialsProvider; return this; diff --git a/src/main/java/com/aliyun/credentials/provider/RsaKeyPairCredentialProvider.java b/src/main/java/com/aliyun/credentials/provider/RsaKeyPairCredentialProvider.java index 972b007..a661897 100644 --- a/src/main/java/com/aliyun/credentials/provider/RsaKeyPairCredentialProvider.java +++ b/src/main/java/com/aliyun/credentials/provider/RsaKeyPairCredentialProvider.java @@ -8,10 +8,7 @@ import com.aliyun.credentials.http.MethodType; import com.aliyun.credentials.models.Config; import com.aliyun.credentials.models.CredentialModel; -import com.aliyun.credentials.utils.AuthConstant; -import com.aliyun.credentials.utils.AuthUtils; -import com.aliyun.credentials.utils.ParameterHelper; -import com.aliyun.credentials.utils.StringUtils; +import com.aliyun.credentials.utils.*; import com.aliyun.tea.utils.Validate; import com.google.gson.Gson; @@ -32,8 +29,8 @@ public class RsaKeyPairCredentialProvider extends SessionCredentialsProvider { /** * Unit of millisecond */ - private int connectTimeout = 1000; - private int readTimeout = 1000; + private int connectTimeout = 5000; + private int readTimeout = 10000; /** * Endpoint of RAM OpenAPI @@ -69,13 +66,28 @@ public RsaKeyPairCredentialProvider(String publicKeyId, String privateKey) { private RsaKeyPairCredentialProvider(BuilderImpl builder) { super(builder); - this.durationSeconds = builder.durationSeconds; + 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.regionId = builder.regionId; - this.connectTimeout = builder.connectionTimeout; - this.readTimeout = builder.readTimeout; - this.STSEndpoint = builder.STSEndpoint; + this.connectTimeout = builder.connectionTimeout == null ? 5000 : builder.connectionTimeout; + this.readTimeout = builder.readTimeout == null ? 10000 : builder.readTimeout; this.publicKeyId = Validate.notNull(builder.publicKeyId, "PublicKeyId must not be null."); - this.privateKeyFile = Validate.notNull(builder.privateKeyFile, "privateKeyFile must not be null."); + this.privateKeyFile = Validate.notNull(builder.privateKeyFile, "PrivateKeyFile must not be null."); + + 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.ap-northeast-1.aliyuncs.com"; + } + } } public static Builder builder() { @@ -133,6 +145,7 @@ public RefreshResult getNewSessionCredentials(CompatibleUrlConn .accessKeyId(result.get("SessionAccessKeyId")) .accessKeySecret(result.get("SessionAccessKeySecret")) .type(AuthConstant.RSA_KEY_PAIR) + .providerName(this.getProviderName()) .expiration(expiration) .build(); return RefreshResult.builder(credential) @@ -196,17 +209,30 @@ public void setSTSEndpoint(String STSEndpoint) { this.STSEndpoint = STSEndpoint; } + @Override + public String getProviderName() { + return ProviderName.RSA_KEY_PAIR; + } + + @Override + public void close() { + } + public interface Builder extends SessionCredentialsProvider.Builder { - Builder durationSeconds(int durationSeconds); + Builder durationSeconds(Integer durationSeconds); Builder regionId(String regionId); - Builder connectionTimeout(int connectionTimeout); + Builder connectionTimeout(Integer connectionTimeout); - Builder readTimeout(int readTimeout); + Builder readTimeout(Integer readTimeout); Builder STSEndpoint(String STSEndpoint); + Builder stsRegionId(String stsRegionId); + + Builder enableVpc(Boolean enableVpc); + Builder publicKeyId(String publicKeyId); Builder privateKeyFile(String privateKeyFile); @@ -218,18 +244,17 @@ public interface Builder extends SessionCredentialsProvider.Builder implements Builder { - - private int durationSeconds = 3600; - - private String regionId = "cn-hangzhou"; - - private int connectionTimeout = 1000; - private int readTimeout = 1000; - private String STSEndpoint = "sts.aliyuncs.com"; + private Integer durationSeconds; + private String regionId; + private Integer connectionTimeout; + private Integer readTimeout; + private String STSEndpoint; + private String stsRegionId; + private Boolean enableVpc; private String publicKeyId; private String privateKeyFile; - public Builder durationSeconds(int durationSeconds) { + public Builder durationSeconds(Integer durationSeconds) { this.durationSeconds = durationSeconds; return this; } @@ -241,12 +266,12 @@ public Builder regionId(String regionId) { return this; } - public Builder connectionTimeout(int connectionTimeout) { + public Builder connectionTimeout(Integer connectionTimeout) { this.connectionTimeout = connectionTimeout; return this; } - public Builder readTimeout(int readTimeout) { + public Builder readTimeout(Integer readTimeout) { this.readTimeout = readTimeout; return this; } @@ -256,6 +281,16 @@ public Builder STSEndpoint(String STSEndpoint) { return this; } + public Builder stsRegionId(String stsRegionId) { + this.stsRegionId = stsRegionId; + return this; + } + + public Builder enableVpc(Boolean enableVpc) { + this.enableVpc = enableVpc; + return this; + } + public Builder publicKeyId(String publicKeyId) { this.publicKeyId = publicKeyId; return this; diff --git a/src/main/java/com/aliyun/credentials/provider/SessionCredentialsProvider.java b/src/main/java/com/aliyun/credentials/provider/SessionCredentialsProvider.java index d64ad5f..589787e 100644 --- a/src/main/java/com/aliyun/credentials/provider/SessionCredentialsProvider.java +++ b/src/main/java/com/aliyun/credentials/provider/SessionCredentialsProvider.java @@ -5,7 +5,7 @@ import java.util.Date; import java.util.concurrent.Callable; -public abstract class SessionCredentialsProvider implements AlibabaCloudCredentialsProvider, AutoCloseable { +public abstract class SessionCredentialsProvider implements AlibabaCloudCredentialsProvider { private final boolean asyncCredentialUpdateEnabled; private RefreshCachedSupplier credentialsCache; private final Callable> refreshCallable = new Callable>() { diff --git a/src/main/java/com/aliyun/credentials/provider/StaticCredentialsProvider.java b/src/main/java/com/aliyun/credentials/provider/StaticCredentialsProvider.java index 22f5491..8f04750 100644 --- a/src/main/java/com/aliyun/credentials/provider/StaticCredentialsProvider.java +++ b/src/main/java/com/aliyun/credentials/provider/StaticCredentialsProvider.java @@ -30,4 +30,13 @@ public StaticCredentialsProvider build() { return new StaticCredentialsProvider(this); } } + + @Override + public String getProviderName() { + return this.credential.getProviderName(); + } + + @Override + public void close() { + } } diff --git a/src/main/java/com/aliyun/credentials/provider/SystemPropertiesCredentialsProvider.java b/src/main/java/com/aliyun/credentials/provider/SystemPropertiesCredentialsProvider.java index 98fccf8..cf5f3c1 100644 --- a/src/main/java/com/aliyun/credentials/provider/SystemPropertiesCredentialsProvider.java +++ b/src/main/java/com/aliyun/credentials/provider/SystemPropertiesCredentialsProvider.java @@ -3,7 +3,7 @@ import com.aliyun.credentials.exception.CredentialException; import com.aliyun.credentials.models.CredentialModel; import com.aliyun.credentials.utils.AuthConstant; -import com.aliyun.credentials.utils.AuthUtils; +import com.aliyun.credentials.utils.ProviderName; import com.aliyun.credentials.utils.StringUtils; public class SystemPropertiesCredentialsProvider implements AlibabaCloudCredentialsProvider { @@ -27,12 +27,23 @@ public CredentialModel getCredentials() { .accessKeySecret(accessKeySecret) .securityToken(securityToken) .type(AuthConstant.STS) + .providerName(this.getProviderName()) .build(); } return CredentialModel.builder() .accessKeyId(accessKeyId) .accessKeySecret(accessKeySecret) .type(AuthConstant.ACCESS_KEY) + .providerName(this.getProviderName()) .build(); } + + @Override + public String getProviderName() { + return ProviderName.SYSTEM; + } + + @Override + public void close() throws Exception { + } } diff --git a/src/main/java/com/aliyun/credentials/provider/URLCredentialProvider.java b/src/main/java/com/aliyun/credentials/provider/URLCredentialProvider.java index 90159cf..7335257 100644 --- a/src/main/java/com/aliyun/credentials/provider/URLCredentialProvider.java +++ b/src/main/java/com/aliyun/credentials/provider/URLCredentialProvider.java @@ -8,10 +8,7 @@ import com.aliyun.credentials.http.MethodType; import com.aliyun.credentials.models.Config; import com.aliyun.credentials.models.CredentialModel; -import com.aliyun.credentials.utils.AuthConstant; -import com.aliyun.credentials.utils.ParameterHelper; -import com.aliyun.credentials.utils.StringUtils; -import com.aliyun.tea.utils.Validate; +import com.aliyun.credentials.utils.*; import com.google.gson.Gson; import java.net.MalformedURLException; @@ -24,8 +21,8 @@ public class URLCredentialProvider extends SessionCredentialsProvider { /** * Unit of millisecond */ - private int connectTimeout = 1000; - private int readTimeout = 1000; + private int connectTimeout = 5000; + private int readTimeout = 10000; @Deprecated public URLCredentialProvider() { @@ -70,13 +67,17 @@ public URLCredentialProvider(Config config) { private URLCredentialProvider(BuilderImpl builder) { super(builder); + String credentialsURI = builder.credentialsURI == null ? AuthUtils.getEnvironmentCredentialsURI() : builder.credentialsURI; + if (StringUtils.isEmpty(credentialsURI)) { + throw new IllegalArgumentException("Credential URI or environment variable ALIBABA_CLOUD_CREDENTIALS_URI cannot be empty."); + } try { - this.credentialsURI = new URL(Validate.notNull(builder.credentialsURI, "Credentials URI is not valid.")); + this.credentialsURI = new URL(credentialsURI); } catch (MalformedURLException e) { throw new CredentialException("Credential URI is not valid."); } - this.connectTimeout = builder.connectionTimeout; - this.readTimeout = builder.readTimeout; + this.connectTimeout = builder.connectionTimeout == null ? 5000 : builder.connectionTimeout; + this.readTimeout = builder.readTimeout == null ? 10000 : builder.readTimeout; } public static Builder builder() { @@ -127,6 +128,7 @@ RefreshResult getNewSessionCredentials(CompatibleUrlConnClient .accessKeySecret(map.get("AccessKeySecret")) .securityToken(map.get("SecurityToken")) .type(AuthConstant.CREDENTIALS_URI) + .providerName(this.getProviderName()) .expiration(expiration) .build(); return RefreshResult.builder(credential) @@ -157,14 +159,23 @@ public void setReadTimeout(int readTimeout) { this.readTimeout = readTimeout; } + @Override + public String getProviderName() { + return ProviderName.CREDENTIALS_URI; + } + + @Override + public void close() { + } + public interface Builder extends SessionCredentialsProvider.Builder { Builder credentialsURI(URL credentialsURI); Builder credentialsURI(String credentialsURI); - Builder connectionTimeout(int connectionTimeout); + Builder connectionTimeout(Integer connectionTimeout); - Builder readTimeout(int readTimeout); + Builder readTimeout(Integer readTimeout); @Override URLCredentialProvider build(); @@ -174,9 +185,9 @@ private static final class BuilderImpl extends SessionCredentialsProvider.BuilderImpl implements Builder { - private String credentialsURI = System.getenv("ALIBABA_CLOUD_CREDENTIALS_URI"); - private int connectionTimeout = 1000; - private int readTimeout = 1000; + private String credentialsURI; + private Integer connectionTimeout; + private Integer readTimeout; public Builder credentialsURI(URL credentialsURI) { this.credentialsURI = credentialsURI.toString(); @@ -188,12 +199,12 @@ public Builder credentialsURI(String credentialsURI) { return this; } - public Builder connectionTimeout(int connectionTimeout) { + public Builder connectionTimeout(Integer connectionTimeout) { this.connectionTimeout = connectionTimeout; return this; } - public Builder readTimeout(int readTimeout) { + public Builder readTimeout(Integer readTimeout) { this.readTimeout = readTimeout; return this; } diff --git a/src/main/java/com/aliyun/credentials/utils/AuthConstant.java b/src/main/java/com/aliyun/credentials/utils/AuthConstant.java index 4f799b7..486fe36 100644 --- a/src/main/java/com/aliyun/credentials/utils/AuthConstant.java +++ b/src/main/java/com/aliyun/credentials/utils/AuthConstant.java @@ -35,9 +35,8 @@ public class AuthConstant { public static final String RSA_KEY_PAIR = "rsa_key_pair"; public static final String BEARER = "bearer"; public static final String OIDC_ROLE_ARN = "oidc_role_arn"; - @Deprecated + @Deprecated() public static final String URL_STS = "credentials_uri"; - public static final String CREDENTIALS_URI = "credentials_uri"; } diff --git a/src/main/java/com/aliyun/credentials/utils/AuthUtils.java b/src/main/java/com/aliyun/credentials/utils/AuthUtils.java index 3306556..7e78336 100644 --- a/src/main/java/com/aliyun/credentials/utils/AuthUtils.java +++ b/src/main/java/com/aliyun/credentials/utils/AuthUtils.java @@ -14,12 +14,16 @@ public class AuthUtils { private static volatile Boolean disableECSIMDSv1; private static volatile String environmentCredentialsFile; private static volatile String environmentRoleArn; + private static volatile String environmentRoleSessionName; private static volatile String environmentOIDCProviderArn; private static volatile String environmentOIDCTokenFilePath; private static volatile String privateKey; private static volatile String OIDCToken; private static volatile Boolean disableCLIProfile; + private static volatile Boolean disableECSMetaData; private static volatile String environmentCredentialsURI; + private static volatile Boolean enableVpcEndpoint; + private static volatile String environmentSTSRegion; public static String getPrivateKey(String filePath) { FileInputStream in = null; @@ -166,6 +170,16 @@ public static String getEnvironmentRoleArn() { : AuthUtils.environmentRoleArn; } + public static void setEnvironmentRoleSessionName(String environmentRoleSessionName) { + AuthUtils.environmentRoleSessionName = environmentRoleSessionName; + } + + public static String getEnvironmentRoleSessionName() { + return null == AuthUtils.environmentRoleSessionName ? + System.getenv("ALIBABA_CLOUD_ROLE_SESSION_NAME") + : AuthUtils.environmentRoleSessionName; + } + public static void setEnvironmentOIDCProviderArn(String environmentOIDCProviderArn) { AuthUtils.environmentOIDCProviderArn = environmentOIDCProviderArn; } @@ -215,6 +229,19 @@ public static boolean isDisableCLIProfile() { return false; } + public static void disableECSMetaData(boolean disableECSMetaData) { + AuthUtils.disableECSMetaData = disableECSMetaData; + } + + public static boolean isDisableECSMetaData() { + if (null != AuthUtils.disableECSMetaData) { + return AuthUtils.disableECSMetaData; + } else if (null != System.getenv("ALIBABA_CLOUD_ECS_METADATA_DISABLED")) { + return Boolean.parseBoolean(System.getenv("ALIBABA_CLOUD_ECS_METADATA_DISABLED")); + } + return false; + } + public static void setEnvironmentCredentialsURI(String environmentCredentialsURI) { AuthUtils.environmentCredentialsURI = environmentCredentialsURI; } @@ -225,4 +252,27 @@ public static String getEnvironmentCredentialsURI() { : AuthUtils.environmentCredentialsURI; } + public static void enableVpcEndpoint(boolean enableVpcEndpoint) { + AuthUtils.enableVpcEndpoint = enableVpcEndpoint; + } + + public static boolean isEnableVpcEndpoint() { + if (null != AuthUtils.enableVpcEndpoint) { + return AuthUtils.enableVpcEndpoint; + } else if (null != System.getenv("ALIBABA_CLOUD_VPC_ENDPOINT_ENABLED")) { + return Boolean.parseBoolean(System.getenv("ALIBABA_CLOUD_VPC_ENDPOINT_ENABLED")); + } + return false; + } + + public static void setEnvironmentSTSRegion(String environmentSTSRegion) { + AuthUtils.environmentSTSRegion = environmentSTSRegion; + } + + public static String getEnvironmentSTSRegion() { + return null == AuthUtils.environmentSTSRegion ? + System.getenv("ALIBABA_CLOUD_STS_REGION") + : AuthUtils.environmentSTSRegion; + } + } diff --git a/src/main/java/com/aliyun/credentials/utils/ProviderName.java b/src/main/java/com/aliyun/credentials/utils/ProviderName.java new file mode 100644 index 0000000..dd84327 --- /dev/null +++ b/src/main/java/com/aliyun/credentials/utils/ProviderName.java @@ -0,0 +1,20 @@ +package com.aliyun.credentials.utils; + +public final class ProviderName { + public static final String STATIC_AK = "static_ak"; + public static final String STATIC_STS = "static_sts"; + public static final String ECS_RAM_ROLE = "ecs_ram_role"; + public static final String RAM_ROLE_ARN = "ram_role_arn"; + public static final String RSA_KEY_PAIR = "rsa_key_pair"; + public static final String OIDC_ROLE_ARN = "oidc_role_arn"; + public static final String CREDENTIALS_URI = "credentials_uri"; + + public static final String ENV = "env"; + public static final String SYSTEM = "system"; + public static final String PROFILE = "profile"; + public static final String CLI_PROFILE = "cli_profile"; + public static final String DEFAULT = "default"; + + private ProviderName() { + } +} diff --git a/src/test/java/com/aliyun/credentials/ClientTest.java b/src/test/java/com/aliyun/credentials/ClientTest.java index e219d4f..4a67e84 100644 --- a/src/test/java/com/aliyun/credentials/ClientTest.java +++ b/src/test/java/com/aliyun/credentials/ClientTest.java @@ -9,7 +9,6 @@ import org.junit.Test; import org.powermock.api.mockito.PowerMockito; -import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -45,6 +44,7 @@ public void defaultCredentialTest() { } catch (Exception e) { Assert.assertTrue(e.getMessage().contains("Unable to load credentials from any of the providers in the chain")); } + AuthUtils.disableCLIProfile(false); } @Test @@ -61,6 +61,7 @@ public void getProviderTest() throws CredentialException, NoSuchMethodException, config.type = AuthConstant.ECS_RAM_ROLE; Assert.assertTrue(getProvider.invoke(credential, config) instanceof EcsRamRoleCredentialProvider); config.type = AuthConstant.RAM_ROLE_ARN; + config.roleArn = "arn:aws:iam::123456789012:role/test"; Assert.assertTrue(getProvider.invoke(credential, config) instanceof RamRoleArnCredentialProvider); config.type = AuthConstant.RSA_KEY_PAIR; config.publicKeyId = "test"; diff --git a/src/test/java/com/aliyun/credentials/models/ConfigTest.java b/src/test/java/com/aliyun/credentials/models/ConfigTest.java index cdc6305..bf6e217 100644 --- a/src/test/java/com/aliyun/credentials/models/ConfigTest.java +++ b/src/test/java/com/aliyun/credentials/models/ConfigTest.java @@ -12,10 +12,10 @@ public void buildTest() { Map map = new HashMap<>(); Config config = Config.build(map); Assert.assertEquals(21600, (int) config.getMetadataTokenDuration()); - Assert.assertEquals(10000, config.getTimeout()); - Assert.assertEquals(5000, config.getConnectTimeout()); + Assert.assertNull(config.getTimeout()); + Assert.assertNull(config.getConnectTimeout()); Assert.assertEquals(3600, config.getRoleSessionExpiration()); - Assert.assertEquals("sts.aliyuncs.com", config.getSTSEndpoint()); + Assert.assertNull(config.getSTSEndpoint()); map.put("type", "test"); map.put("accessKeyId", "test"); @@ -53,8 +53,8 @@ public void buildTest() { Assert.assertEquals(180, (int) config.getMetadataTokenDuration()); Assert.assertEquals("test", config.getSecurityToken()); Assert.assertEquals("test", config.getHost()); - Assert.assertEquals(2000, config.getTimeout()); - Assert.assertEquals(2000, config.getConnectTimeout()); + Assert.assertEquals(2000, (int) config.getTimeout()); + Assert.assertEquals(2000, (int) config.getConnectTimeout()); Assert.assertEquals("test", config.getPolicy()); Assert.assertEquals(1000, config.getRoleSessionExpiration()); Assert.assertEquals("test", config.getOidcProviderArn()); @@ -100,12 +100,12 @@ public void setterTest() { Assert.assertEquals("test", config.getRoleName()); Assert.assertEquals(true, config.getEnableIMDSv2()); Assert.assertEquals(true, config.getDisableIMDSv1()); - Assert.assertEquals(180, (int)config.getMetadataTokenDuration()); + Assert.assertEquals(180, (int) config.getMetadataTokenDuration()); Assert.assertEquals(180, (int) config.getMetadataTokenDuration()); Assert.assertEquals("test", config.getSecurityToken()); Assert.assertEquals("test", config.getHost()); - Assert.assertEquals(2000, config.getTimeout()); - Assert.assertEquals(2000, config.getConnectTimeout()); + Assert.assertEquals(2000, (int) config.getTimeout()); + Assert.assertEquals(2000, (int) config.getConnectTimeout()); Assert.assertEquals("test", config.getPolicy()); Assert.assertEquals(1000, config.getRoleSessionExpiration()); Assert.assertEquals("test", config.getOidcProviderArn()); diff --git a/src/test/java/com/aliyun/credentials/provider/DefaultCredentialsProviderTest.java b/src/test/java/com/aliyun/credentials/provider/DefaultCredentialsProviderTest.java index e07f6e7..04d1359 100644 --- a/src/test/java/com/aliyun/credentials/provider/DefaultCredentialsProviderTest.java +++ b/src/test/java/com/aliyun/credentials/provider/DefaultCredentialsProviderTest.java @@ -19,8 +19,18 @@ public CredentialModel getCredentials() { .accessKeyId("") .accessKeySecret("") .type(AuthConstant.ACCESS_KEY) + .providerName(this.getProviderName()) .build(); } + + @Override + public String getProviderName() { + return "test"; + } + + @Override + public void close() { + } } @Test @@ -42,14 +52,9 @@ public void getCredentialsTest() throws NoSuchFieldException, IllegalAccessExcep DefaultCredentialsProvider provider = DefaultCredentialsProvider.builder() .reuseLastProviderEnabled(false) .build(); + new DefaultCredentialsProvider(); AuthUtils.setEnvironmentECSMetaData(""); - try { - new DefaultCredentialsProvider(); - Assert.fail(); - } catch (CredentialException e) { - Assert.assertEquals("Failed to get RAM session credentials from ECS metadata service. HttpCode=0", - e.getMessage()); - } + new DefaultCredentialsProvider(); AuthUtils.setEnvironmentAccessKeyId("test"); AuthUtils.setEnvironmentAccessKeySecret("test"); @@ -62,6 +67,15 @@ public void getCredentialsTest() throws NoSuchFieldException, IllegalAccessExcep public CredentialModel getCredentials() { throw new CredentialException("test"); } + + @Override + public String getProviderName() { + return ""; + } + + @Override + public void close() { + } }); DefaultCredentialsProvider.addCredentialsProvider(new CredentialsProviderForTest()); credential = provider.getCredentials(); diff --git a/src/test/java/com/aliyun/credentials/provider/ECSMetadataServiceCredentialsFetcherTest.java b/src/test/java/com/aliyun/credentials/provider/ECSMetadataServiceCredentialsFetcherTest.java index 4011b8e..bc8ba5c 100644 --- a/src/test/java/com/aliyun/credentials/provider/ECSMetadataServiceCredentialsFetcherTest.java +++ b/src/test/java/com/aliyun/credentials/provider/ECSMetadataServiceCredentialsFetcherTest.java @@ -24,14 +24,14 @@ public void constructorTest() { fetcher = new ECSMetadataServiceCredentialsFetcher("test", 800, 800); Assert.assertEquals("test", fetcher.getRoleName()); - Assert.assertEquals(1000, fetcher.getReadTimeout()); - Assert.assertEquals(1000, fetcher.getConnectionTimeout()); + Assert.assertEquals(800, fetcher.getReadTimeout()); + Assert.assertEquals(800, fetcher.getConnectionTimeout()); Assert.assertFalse(fetcher.getDisableIMDSv1()); Assert.assertEquals(21600, fetcher.getMetadataTokenDuration()); fetcher = new ECSMetadataServiceCredentialsFetcher("id", 1200, 800); Assert.assertEquals("id", fetcher.getRoleName()); - Assert.assertEquals(1000, fetcher.getReadTimeout()); + Assert.assertEquals(800, fetcher.getReadTimeout()); Assert.assertEquals(1200, fetcher.getConnectionTimeout()); Assert.assertFalse(fetcher.getDisableIMDSv1()); Assert.assertEquals(21600, fetcher.getMetadataTokenDuration()); @@ -39,21 +39,21 @@ public void constructorTest() { fetcher = new ECSMetadataServiceCredentialsFetcher("id", 900, 1200); Assert.assertEquals("id", fetcher.getRoleName()); Assert.assertEquals(1200, fetcher.getReadTimeout()); - Assert.assertEquals(1000, fetcher.getConnectionTimeout()); + Assert.assertEquals(900, fetcher.getConnectionTimeout()); Assert.assertFalse(fetcher.getDisableIMDSv1()); Assert.assertEquals(21600, fetcher.getMetadataTokenDuration()); fetcher = new ECSMetadataServiceCredentialsFetcher("id", true, 180, 900, 1200); Assert.assertEquals("id", fetcher.getRoleName()); Assert.assertEquals(1200, fetcher.getReadTimeout()); - Assert.assertEquals(1000, fetcher.getConnectionTimeout()); + Assert.assertEquals(900, fetcher.getConnectionTimeout()); Assert.assertTrue(fetcher.getDisableIMDSv1()); Assert.assertEquals(21600, fetcher.getMetadataTokenDuration()); fetcher = new ECSMetadataServiceCredentialsFetcher("id", true, 900, 1200); Assert.assertEquals("id", fetcher.getRoleName()); Assert.assertEquals(1200, fetcher.getReadTimeout()); - Assert.assertEquals(1000, fetcher.getConnectionTimeout()); + Assert.assertEquals(900, fetcher.getConnectionTimeout()); Assert.assertTrue(fetcher.getDisableIMDSv1()); Assert.assertEquals(21600, fetcher.getMetadataTokenDuration()); } diff --git a/src/test/java/com/aliyun/credentials/provider/EcsRamRoleCredentialProviderTest.java b/src/test/java/com/aliyun/credentials/provider/EcsRamRoleCredentialProviderTest.java index bd60674..64f2ddf 100644 --- a/src/test/java/com/aliyun/credentials/provider/EcsRamRoleCredentialProviderTest.java +++ b/src/test/java/com/aliyun/credentials/provider/EcsRamRoleCredentialProviderTest.java @@ -6,6 +6,7 @@ import com.aliyun.credentials.models.Config; import com.aliyun.credentials.models.CredentialModel; import com.aliyun.credentials.utils.AuthConstant; +import com.aliyun.credentials.utils.AuthUtils; import com.aliyun.credentials.utils.ParameterHelper; import org.junit.Assert; import org.junit.Test; diff --git a/src/test/java/com/aliyun/credentials/provider/OIDCRoleArnCredentialProviderTest.java b/src/test/java/com/aliyun/credentials/provider/OIDCRoleArnCredentialProviderTest.java index 261c3f9..2a9857f 100644 --- a/src/test/java/com/aliyun/credentials/provider/OIDCRoleArnCredentialProviderTest.java +++ b/src/test/java/com/aliyun/credentials/provider/OIDCRoleArnCredentialProviderTest.java @@ -7,6 +7,7 @@ import com.aliyun.credentials.http.HttpResponse; import com.aliyun.credentials.models.Config; import com.aliyun.credentials.utils.AuthConstant; +import com.aliyun.credentials.utils.AuthUtils; import org.junit.Assert; import org.junit.Test; import org.mockito.ArgumentMatchers; @@ -182,4 +183,116 @@ public void getSetTest() { Assert.assertEquals("www.aliyun.com", provider.getSTSEndpoint()); } + @Test + public void builderTest() { + OIDCRoleArnCredentialProvider provider; + try { + OIDCRoleArnCredentialProvider.builder().build(); + Assert.fail(); + } catch (Exception e) { + Assert.assertEquals("RoleArn or environment variable ALIBABA_CLOUD_ROLE_ARN cannot be empty.", e.getMessage()); + } + + try { + OIDCRoleArnCredentialProvider.builder() + .roleArn("test") + .build(); + Assert.fail(); + } catch (Exception e) { + Assert.assertEquals("OIDCProviderArn or environment variable ALIBABA_CLOUD_OIDC_PROVIDER_ARN cannot be empty.", e.getMessage()); + } + + try { + OIDCRoleArnCredentialProvider.builder() + .roleArn("test") + .oidcProviderArn("test") + .build(); + Assert.fail(); + } catch (Exception e) { + Assert.assertEquals("OIDCTokenFilePath or environment variable ALIBABA_CLOUD_OIDC_TOKEN_FILE cannot be empty.", e.getMessage()); + } + + try { + OIDCRoleArnCredentialProvider.builder() + .durationSeconds(100) + .build(); + Assert.fail(); + } catch (Exception e) { + Assert.assertEquals("Session duration should be in the range of 900s - max session duration.", e.getMessage()); + } + + provider = OIDCRoleArnCredentialProvider.builder() + .roleArn("test") + .oidcProviderArn("test") + .oidcTokenFilePath("OIDCToken.txt") + .build(); + Assert.assertEquals("sts.aliyuncs.com", provider.getSTSEndpoint()); + + provider = OIDCRoleArnCredentialProvider.builder() + .roleArn("test") + .oidcProviderArn("test") + .oidcTokenFilePath("OIDCToken.txt") + .stsRegionId("cn-hangzhou") + .build(); + Assert.assertEquals("sts.cn-hangzhou.aliyuncs.com", provider.getSTSEndpoint()); + + AuthUtils.enableVpcEndpoint(true); + provider = OIDCRoleArnCredentialProvider.builder() + .roleArn("test") + .oidcProviderArn("test") + .oidcTokenFilePath("OIDCToken.txt") + .stsRegionId("cn-hangzhou") + .build(); + Assert.assertEquals("sts-vpc.cn-hangzhou.aliyuncs.com", provider.getSTSEndpoint()); + AuthUtils.enableVpcEndpoint(false); + + provider = OIDCRoleArnCredentialProvider.builder() + .roleArn("test") + .oidcProviderArn("test") + .oidcTokenFilePath("OIDCToken.txt") + .stsRegionId("cn-hangzhou") + .enableVpc(true) + .build(); + Assert.assertEquals("sts-vpc.cn-hangzhou.aliyuncs.com", provider.getSTSEndpoint()); + + provider = OIDCRoleArnCredentialProvider.builder() + .roleArn("test") + .oidcProviderArn("test") + .oidcTokenFilePath("OIDCToken.txt") + .STSEndpoint("sts.cn-shanghai.aliyuncs.com") + .stsRegionId("cn-hangzhou") + .enableVpc(true) + .build(); + Assert.assertEquals("sts.cn-shanghai.aliyuncs.com", provider.getSTSEndpoint()); + + String filePath = OIDCRoleArnCredentialProviderTest.class.getClassLoader(). + getResource("OIDCToken.txt").getPath(); + provider = OIDCRoleArnCredentialProvider.builder() + .roleArn("test") + .oidcProviderArn("test") + .oidcTokenFilePath(filePath) + .durationSeconds(1000) + .roleSessionName("test") + .policy("test") + .STSEndpoint("sts.aliyuncs.com") + .regionId("cn-hangzhou") + .connectionTimeout(2000) + .readTimeout(2000) + .build(); + Assert.assertEquals(2000, provider.getConnectTimeout()); + Assert.assertEquals(2000, provider.getReadTimeout()); + Assert.assertEquals(1000, provider.getDurationSeconds()); + Assert.assertEquals("test", provider.getRoleArn()); + Assert.assertEquals("test", provider.getRoleSessionName()); + Assert.assertEquals("test", provider.getPolicy()); + Assert.assertEquals("sts.aliyuncs.com", provider.getSTSEndpoint()); + Assert.assertEquals("cn-hangzhou", provider.getRegionId()); + try { + provider.getCredentials(); + Assert.fail(); + } catch (Exception e) { + Assert.assertTrue(e.getMessage().contains("Error refreshing credentials from OIDC, HttpCode: 400")); + } + } + } \ No newline at end of file diff --git a/src/test/java/com/aliyun/credentials/provider/ProfileCredentialsProviderTest.java b/src/test/java/com/aliyun/credentials/provider/ProfileCredentialsProviderTest.java index 4a28c1c..4f87ed4 100644 --- a/src/test/java/com/aliyun/credentials/provider/ProfileCredentialsProviderTest.java +++ b/src/test/java/com/aliyun/credentials/provider/ProfileCredentialsProviderTest.java @@ -1,6 +1,7 @@ package com.aliyun.credentials.provider; import com.aliyun.credentials.exception.CredentialException; +import com.aliyun.credentials.models.CredentialModel; import com.aliyun.credentials.utils.AuthConstant; import com.aliyun.credentials.utils.AuthUtils; import org.ini4j.Wini; @@ -72,15 +73,39 @@ public void createCredentialTest() throws NoSuchMethodException, InvocationTarge client.put(AuthConstant.INI_TYPE, AuthConstant.ACCESS_KEY); client.put(AuthConstant.INI_ACCESS_KEY_ID, "test"); client.put(AuthConstant.INI_ACCESS_KEY_IDSECRET, null); - Assert.assertNull(createCredential.invoke(provider, client, factory)); + try { + createCredential.invoke(provider, client, factory); + Assert.fail(); + } catch (Exception e) { + Assert.assertEquals("The configured access_key_id or access_key_secret is empty.", + e.getCause().getLocalizedMessage()); + } client.put(AuthConstant.INI_ACCESS_KEY_ID, null); - Assert.assertNull(createCredential.invoke(provider, client, factory)); + try { + createCredential.invoke(provider, client, factory); + Assert.fail(); + } catch (Exception e) { + Assert.assertEquals("The configured access_key_id or access_key_secret is empty.", + e.getCause().getLocalizedMessage()); + } + + client.clear(); + client.put(AuthConstant.INI_ACCESS_KEY_ID, AuthConstant.INI_TYPE_RAM); + client.put(AuthConstant.INI_TYPE, "access_key"); + try { + createCredential.invoke(provider, client, factory); + Assert.fail(); + } catch (Exception e) { + Assert.assertEquals("The configured access_key_id or access_key_secret is empty.", + e.getCause().getLocalizedMessage()); + } client.clear(); client.put(AuthConstant.INI_ACCESS_KEY_ID, AuthConstant.INI_TYPE_RAM); + client.put(AuthConstant.INI_ACCESS_KEY_IDSECRET, AuthConstant.INI_TYPE_RAM); client.put(AuthConstant.INI_TYPE, "access_key"); - Assert.assertNull(createCredential.invoke(provider, client, factory)); + Assert.assertNotNull(createCredential.invoke(provider, client, factory)); } @Test @@ -236,11 +261,11 @@ public void createCredentialsProviderTest() throws client.put(AuthConstant.DEFAULT_REGION, AuthConstant.INI_TYPE_ARN); RamRoleArnCredentialProvider ramRoleArnCredentialProvider = Mockito.mock(RamRoleArnCredentialProvider.class); - Mockito.when(ramRoleArnCredentialProvider.getCredentials()).thenReturn(null); + Mockito.when(ramRoleArnCredentialProvider.getCredentials()).thenReturn(CredentialModel.builder().build()); CredentialsProviderFactory factory = Mockito.mock(CredentialsProviderFactory.class); Mockito.when(factory.createCredentialsProvider(Mockito.any(RamRoleArnCredentialProvider.class))). thenReturn(ramRoleArnCredentialProvider); - Assert.assertNull(createCredential.invoke(profileCredentialsProvider, client, factory)); + Assert.assertNotNull(createCredential.invoke(profileCredentialsProvider, client, factory)); client.clear(); client.put(AuthConstant.INI_TYPE, AuthConstant.INI_TYPE_OIDC); @@ -255,10 +280,10 @@ public void createCredentialsProviderTest() throws OIDCRoleArnCredentialProvider oidcRoleArnCredentialProvider = Mockito.mock(OIDCRoleArnCredentialProvider.class); - Mockito.when(oidcRoleArnCredentialProvider.getCredentials()).thenReturn(null); + Mockito.when(oidcRoleArnCredentialProvider.getCredentials()).thenReturn(CredentialModel.builder().build()); Mockito.when(factory.createCredentialsProvider(Mockito.any(OIDCRoleArnCredentialProvider.class))). thenReturn(oidcRoleArnCredentialProvider); - Assert.assertNull(createCredential.invoke(profileCredentialsProvider, client, factory)); + Assert.assertNotNull(createCredential.invoke(profileCredentialsProvider, client, factory)); client.clear(); client.put(AuthConstant.INI_TYPE, AuthConstant.INI_TYPE_KEY_PAIR); @@ -268,7 +293,7 @@ public void createCredentialsProviderTest() throws AuthUtils.setPrivateKey("test"); RsaKeyPairCredentialProvider rsaKeyPairCredentialProvider = Mockito.mock(RsaKeyPairCredentialProvider.class); - Mockito.when(rsaKeyPairCredentialProvider.getCredentials()).thenReturn(null); + Mockito.when(rsaKeyPairCredentialProvider.getCredentials()).thenReturn(CredentialModel.builder().build()); Mockito.when(factory.createCredentialsProvider(Mockito.any(RsaKeyPairCredentialProvider.class))). thenReturn(rsaKeyPairCredentialProvider); try { @@ -285,10 +310,10 @@ public void createCredentialsProviderTest() throws client.put(AuthConstant.INI_ROLE_NAME, AuthConstant.INI_TYPE_KEY_PAIR); EcsRamRoleCredentialProvider ecsRamRoleCredentialProvider = Mockito.mock(EcsRamRoleCredentialProvider.class); - Mockito.when(ecsRamRoleCredentialProvider.getCredentials()).thenReturn(null); + Mockito.when(ecsRamRoleCredentialProvider.getCredentials()).thenReturn(CredentialModel.builder().build()); Mockito.when(factory.createCredentialsProvider(Mockito.any(EcsRamRoleCredentialProvider.class))). thenReturn(ecsRamRoleCredentialProvider); - Assert.assertNull(createCredential.invoke(profileCredentialsProvider, client, factory)); + Assert.assertNotNull(createCredential.invoke(profileCredentialsProvider, client, factory)); } @Test diff --git a/src/test/java/com/aliyun/credentials/provider/RamRoleArnCredentialProviderTest.java b/src/test/java/com/aliyun/credentials/provider/RamRoleArnCredentialProviderTest.java index 1221e64..54febd1 100644 --- a/src/test/java/com/aliyun/credentials/provider/RamRoleArnCredentialProviderTest.java +++ b/src/test/java/com/aliyun/credentials/provider/RamRoleArnCredentialProviderTest.java @@ -7,6 +7,7 @@ import com.aliyun.credentials.http.HttpResponse; import com.aliyun.credentials.models.Config; import com.aliyun.credentials.utils.AuthConstant; +import com.aliyun.credentials.utils.AuthUtils; import org.junit.Assert; import org.junit.Test; import org.mockito.ArgumentMatchers; @@ -148,7 +149,73 @@ public void getSetTest() { @Test public void builderTest() { - RamRoleArnCredentialProvider originalProvider = RamRoleArnCredentialProvider.builder() + RamRoleArnCredentialProvider originalProvider; + try { + RamRoleArnCredentialProvider.builder().build(); + Assert.fail(); + } catch (Exception e) { + Assert.assertEquals("RoleArn or environment variable ALIBABA_CLOUD_ROLE_ARN cannot be empty.", e.getMessage()); + } + + try { + RamRoleArnCredentialProvider.builder() + .durationSeconds(100) + .build(); + Assert.fail(); + } catch (Exception e) { + Assert.assertEquals("Session duration should be in the range of 900s - max session duration.", e.getMessage()); + } + + originalProvider = RamRoleArnCredentialProvider.builder() + .accessKeyId("test") + .accessKeySecret("test") + .securityToken("test") + .roleArn("test") + .build(); + Assert.assertEquals("sts.aliyuncs.com", originalProvider.getSTSEndpoint()); + + originalProvider = RamRoleArnCredentialProvider.builder() + .accessKeyId("test") + .accessKeySecret("test") + .securityToken("test") + .stsRegionId("cn-hangzhou") + .roleArn("test") + .build(); + Assert.assertEquals("sts.cn-hangzhou.aliyuncs.com", originalProvider.getSTSEndpoint()); + + AuthUtils.enableVpcEndpoint(true); + originalProvider = RamRoleArnCredentialProvider.builder() + .accessKeyId("test") + .accessKeySecret("test") + .securityToken("test") + .stsRegionId("cn-hangzhou") + .roleArn("test") + .build(); + Assert.assertEquals("sts-vpc.cn-hangzhou.aliyuncs.com", originalProvider.getSTSEndpoint()); + AuthUtils.enableVpcEndpoint(false); + + originalProvider = RamRoleArnCredentialProvider.builder() + .accessKeyId("test") + .accessKeySecret("test") + .securityToken("test") + .stsRegionId("cn-hangzhou") + .enableVpc(true) + .roleArn("test") + .build(); + Assert.assertEquals("sts-vpc.cn-hangzhou.aliyuncs.com", originalProvider.getSTSEndpoint()); + + originalProvider = RamRoleArnCredentialProvider.builder() + .accessKeyId("test") + .accessKeySecret("test") + .securityToken("test") + .STSEndpoint("sts.cn-shanghai.aliyuncs.com") + .stsRegionId("cn-hangzhou") + .enableVpc(true) + .roleArn("test") + .build(); + Assert.assertEquals("sts.cn-shanghai.aliyuncs.com", originalProvider.getSTSEndpoint()); + + originalProvider = RamRoleArnCredentialProvider.builder() .accessKeyId("test") .accessKeySecret("test") .durationSeconds(1000) @@ -185,7 +252,7 @@ public void builderTest() { .roleArn("test") .build(); Assert.assertEquals("test", provider.getRoleArn()); - Assert.assertEquals("javaSdkRoleSessionName", provider.getRoleSessionName()); + Assert.assertTrue(provider.getRoleSessionName().contains("credentials-java-")); Assert.assertEquals("sts.aliyuncs.com", provider.getSTSEndpoint()); try { provider.getCredentials(); diff --git a/src/test/java/com/aliyun/credentials/provider/RsaKeyPairCredentialProviderTest.java b/src/test/java/com/aliyun/credentials/provider/RsaKeyPairCredentialProviderTest.java index e11a11e..e9ef778 100644 --- a/src/test/java/com/aliyun/credentials/provider/RsaKeyPairCredentialProviderTest.java +++ b/src/test/java/com/aliyun/credentials/provider/RsaKeyPairCredentialProviderTest.java @@ -7,6 +7,7 @@ import com.aliyun.credentials.http.HttpResponse; import com.aliyun.credentials.models.Config; import com.aliyun.credentials.utils.AuthConstant; +import com.aliyun.credentials.utils.AuthUtils; import org.junit.Assert; import org.junit.Test; import org.mockito.ArgumentMatchers; @@ -93,4 +94,88 @@ public void getSet() { provider.setSTSEndpoint("www.aliyun.com"); Assert.assertEquals("www.aliyun.com", provider.getSTSEndpoint()); } + + @Test + public void builderTest() { + RsaKeyPairCredentialProvider provider; + try { + RsaKeyPairCredentialProvider.builder().build(); + Assert.fail(); + } catch (Exception e) { + Assert.assertEquals("PublicKeyId must not be null.", e.getMessage()); + } + + try { + RsaKeyPairCredentialProvider.builder() + .publicKeyId("test") + .build(); + Assert.fail(); + } catch (Exception e) { + Assert.assertEquals("PrivateKeyFile must not be null.", e.getMessage()); + } + + try { + RsaKeyPairCredentialProvider.builder() + .durationSeconds(100) + .build(); + Assert.fail(); + } catch (Exception e) { + Assert.assertEquals("Session duration should be in the range of 900s - max session duration.", e.getMessage()); + } + + provider = RsaKeyPairCredentialProvider.builder() + .publicKeyId("test") + .privateKeyFile("test") + .build(); + Assert.assertEquals("sts.ap-northeast-1.aliyuncs.com", provider.getSTSEndpoint()); + + provider = RsaKeyPairCredentialProvider.builder() + .publicKeyId("test") + .privateKeyFile("test") + .stsRegionId("cn-hangzhou") + .build(); + Assert.assertEquals("sts.cn-hangzhou.aliyuncs.com", provider.getSTSEndpoint()); + + AuthUtils.enableVpcEndpoint(true); + provider = RsaKeyPairCredentialProvider.builder() + .publicKeyId("test") + .privateKeyFile("test") + .stsRegionId("cn-hangzhou") + .build(); + Assert.assertEquals("sts-vpc.cn-hangzhou.aliyuncs.com", provider.getSTSEndpoint()); + AuthUtils.enableVpcEndpoint(false); + + provider = RsaKeyPairCredentialProvider.builder() + .publicKeyId("test") + .privateKeyFile("test") + .stsRegionId("cn-hangzhou") + .enableVpc(true) + .build(); + Assert.assertEquals("sts-vpc.cn-hangzhou.aliyuncs.com", provider.getSTSEndpoint()); + + provider = RsaKeyPairCredentialProvider.builder() + .publicKeyId("test") + .privateKeyFile("test") + .STSEndpoint("sts.cn-shanghai.aliyuncs.com") + .stsRegionId("cn-hangzhou") + .enableVpc(true) + .build(); + Assert.assertEquals("sts.cn-shanghai.aliyuncs.com", provider.getSTSEndpoint()); + + provider = RsaKeyPairCredentialProvider.builder() + .publicKeyId("test") + .privateKeyFile("test") + .durationSeconds(1000) + .STSEndpoint("sts.aliyuncs.com") + .regionId("cn-hangzhou") + .connectionTimeout(2000) + .readTimeout(2000) + .build(); + Assert.assertEquals(2000, provider.getConnectTimeout()); + Assert.assertEquals(2000, provider.getReadTimeout()); + Assert.assertEquals(1000, provider.getDurationSeconds()); + Assert.assertEquals("test", provider.getPublicKeyId()); + Assert.assertEquals("sts.aliyuncs.com", provider.getSTSEndpoint()); + Assert.assertEquals("cn-hangzhou", provider.getRegionId()); + } } diff --git a/src/test/java/com/aliyun/credentials/provider/URLCredentialProviderTest.java b/src/test/java/com/aliyun/credentials/provider/URLCredentialProviderTest.java index c91bade..e65272a 100644 --- a/src/test/java/com/aliyun/credentials/provider/URLCredentialProviderTest.java +++ b/src/test/java/com/aliyun/credentials/provider/URLCredentialProviderTest.java @@ -6,6 +6,7 @@ import com.aliyun.credentials.http.HttpRequest; import com.aliyun.credentials.http.HttpResponse; import com.aliyun.credentials.utils.AuthConstant; +import com.aliyun.credentials.utils.AuthUtils; import org.junit.Assert; import org.junit.Test; import org.mockito.ArgumentMatchers; diff --git a/src/test/java/com/aliyun/credentials/utils/AuthUtilsTest.java b/src/test/java/com/aliyun/credentials/utils/AuthUtilsTest.java index db21908..178c590 100644 --- a/src/test/java/com/aliyun/credentials/utils/AuthUtilsTest.java +++ b/src/test/java/com/aliyun/credentials/utils/AuthUtilsTest.java @@ -68,6 +68,34 @@ public void environmentTest() { AuthUtils.setEnvironmentOIDCProviderArn(null); AuthUtils.setEnvironmentOIDCTokenFilePath(null); Assert.assertFalse(AuthUtils.environmentEnableOIDC()); + + Assert.assertNull(AuthUtils.getEnvironmentRoleSessionName()); + AuthUtils.setEnvironmentRoleSessionName("test"); + Assert.assertEquals("test", AuthUtils.getEnvironmentRoleSessionName()); + AuthUtils.setEnvironmentRoleSessionName(null); + + Assert.assertNull(AuthUtils.getEnvironmentSTSRegion()); + AuthUtils.setEnvironmentSTSRegion("test"); + Assert.assertEquals("test", AuthUtils.getEnvironmentSTSRegion()); + AuthUtils.setEnvironmentSTSRegion(null); + + Assert.assertFalse(AuthUtils.isDisableECSMetaData()); + AuthUtils.disableECSMetaData(true); + Assert.assertTrue(AuthUtils.isDisableECSMetaData()); + AuthUtils.disableECSMetaData(false); + Assert.assertFalse(AuthUtils.isDisableECSMetaData()); + + Assert.assertFalse(AuthUtils.isEnableVpcEndpoint()); + AuthUtils.enableVpcEndpoint(true); + Assert.assertTrue(AuthUtils.isEnableVpcEndpoint()); + AuthUtils.enableVpcEndpoint(false); + Assert.assertFalse(AuthUtils.isEnableVpcEndpoint()); + + Assert.assertFalse(AuthUtils.isDisableCLIProfile()); + AuthUtils.disableCLIProfile(true); + Assert.assertTrue(AuthUtils.isDisableCLIProfile()); + AuthUtils.disableCLIProfile(false); + Assert.assertFalse(AuthUtils.isDisableCLIProfile()); } @Test