Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e122668

Browse files
atptroJacksonTian
authored andcommitted
add credential chain
1 parent c173bbc commit e122668

26 files changed

+954
-64
lines changed

aliyun-java-sdk-core/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,11 @@
113113
<version>0.8.3</version>
114114
<classifier>runtime</classifier>
115115
</dependency>
116+
<dependency>
117+
<groupId>org.ini4j</groupId>
118+
<artifactId>ini4j</artifactId>
119+
<version>0.5.4</version>
120+
</dependency>
116121
</dependencies>
117122

118123
<build>

aliyun-java-sdk-core/src/main/java/com/aliyuncs/DefaultAcsClient.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,17 @@ public class DefaultAcsClient implements IAcsClient {
3535
private boolean autoRetry = true;
3636
private IClientProfile clientProfile = null;
3737
private AlibabaCloudCredentialsProvider credentialsProvider;
38+
private DefaultCredentialsProvider defaultCredentialsProvider;
3839

3940
private IHttpClient httpClient;
4041
private EndpointResolver endpointResolver;
4142
private static final String SIGNATURE_BEGIN = "string to sign is:";
4243
private final UserAgentConfig userAgentConfig = new UserAgentConfig();
4344

44-
@Deprecated
45-
public DefaultAcsClient() {
45+
public DefaultAcsClient() throws ClientException {
4646
this.clientProfile = DefaultProfile.getProfile();
4747
this.httpClient = HttpClientFactory.buildClient(this.clientProfile);
48+
this.defaultCredentialsProvider = new DefaultCredentialsProvider();
4849
}
4950

5051
public DefaultAcsClient(IClientProfile profile) {
@@ -165,8 +166,12 @@ public <T extends AcsResponse> HttpResponse doAction(AcsRequest<T> request, bool
165166
if (null == request.getSysRegionId()) {
166167
request.setSysRegionId(region);
167168
}
168-
169-
AlibabaCloudCredentials credentials = this.credentialsProvider.getCredentials();
169+
AlibabaCloudCredentials credentials;
170+
if (null == credentialsProvider) {
171+
credentials = this.defaultCredentialsProvider.getCredentials();
172+
} else {
173+
credentials = this.credentialsProvider.getCredentials();
174+
}
170175
Signer signer = Signer.getSigner(credentials);
171176
FormatType format = profile.getFormat();
172177

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.aliyuncs.auth;
2+
3+
public class AuthConstant {
4+
public static final String SYSTEM_ACCESSKEYID = "alibabacloud.accessKeyId";
5+
public static final String SYSTEM_ACCESSKEYSECRET = "alibabacloud.accessKeyIdSecret";
6+
7+
public static final String DEFAULT_CREDENTIALS_FILE_PATH = System.getProperty("user.home") +
8+
"/.alibabacloud/credentials.ini";
9+
public static final String INI_ACCESS_KEY_ID = "access_key_id";
10+
public static final String INI_ACCESS_KEY_IDSECRET = "access_key_secret";
11+
public static final String INI_TYPE = "type";
12+
public static final String INI_TYPE_RAM = "ecs_ram_role";
13+
public static final String INI_TYPE_ARN = "ram_role_arn";
14+
public static final String INI_TYPE_KEY_PAIR = "rsa_key_pair";
15+
public static final String INI_PUBLIC_KEY_ID = "public_key_id";
16+
public static final String INI_PRIVATE_KEY_FILE = "private_key_file";
17+
public static final String INI_PRIVATE_KEY = "private_key";
18+
public static final String INI_ROLE_NAME = "role_name";
19+
public static final String INI_ROLE_SESSION_NAME = "role_session_name";
20+
public static final String INI_ROLE_ARN = "role_arn";
21+
22+
public static final long TSC_VALID_TIME_SECONDS = 3600L;
23+
public static final String DEFAULT_REGION = "cn-hangzhou";
24+
public static final String INI_ENABLE = "enable";
25+
26+
}

aliyun-java-sdk-core/src/main/java/com/aliyuncs/auth/BasicSessionCredentials.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ public class BasicSessionCredentials implements AlibabaCloudCredentials {
66
private final String accessKeyId;
77
private final String accessKeySecret;
88
private final String sessionToken;
9-
private final double expireFact = 0.8;
9+
private final double expireFact = 0.95;
1010
private long sessionStartedTimeInMilliSeconds = 0;
1111

1212
public BasicSessionCredentials(String accessKeyId, String accessKeySecret, String sessionToken) {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.aliyuncs.auth;
2+
3+
public class CredentialsProviderFactory {
4+
public <T extends AlibabaCloudCredentialsProvider> T createCredentialsProvider(T classInstance) {
5+
return classInstance;
6+
}
7+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package com.aliyuncs.auth;
2+
3+
import com.aliyuncs.exceptions.ClientException;
4+
import com.aliyuncs.utils.AuthUtils;
5+
6+
import java.util.ArrayList;
7+
import java.util.List;
8+
import java.util.Vector;
9+
10+
public class DefaultCredentialsProvider implements AlibabaCloudCredentialsProvider {
11+
private List<AlibabaCloudCredentialsProvider> defaultProviders = new ArrayList<AlibabaCloudCredentialsProvider>();
12+
private static final List<AlibabaCloudCredentialsProvider> userConfigurationProviders =
13+
new Vector<AlibabaCloudCredentialsProvider>();
14+
15+
public DefaultCredentialsProvider() throws ClientException {
16+
defaultProviders.add(new SystemPropertiesCredentialsProvider());
17+
defaultProviders.add(new EnvironmentVariableCredentialsProvider());
18+
defaultProviders.add(new ProfileCredentialsProvider());
19+
String roleName = AuthUtils.getEnvironmentECSMetaData();
20+
if (roleName != null) {
21+
if (roleName.length() == 0) {
22+
throw new ClientException("Environment variable roleName('ALIBABA_CLOUD_ECS_METADATA') cannot be empty");
23+
}
24+
defaultProviders.add(new InstanceProfileCredentialsProvider(roleName));
25+
}
26+
}
27+
28+
@Override
29+
public AlibabaCloudCredentials getCredentials() throws ClientException {
30+
AlibabaCloudCredentials credential;
31+
if (userConfigurationProviders.size() > 0) {
32+
for (AlibabaCloudCredentialsProvider provider : userConfigurationProviders) {
33+
credential = provider.getCredentials();
34+
if (null != credential) {
35+
return credential;
36+
}
37+
}
38+
}
39+
for (AlibabaCloudCredentialsProvider provider : defaultProviders) {
40+
credential = provider.getCredentials();
41+
if (null != credential) {
42+
return credential;
43+
}
44+
}
45+
throw new ClientException("not found credentials");
46+
}
47+
48+
public static boolean addCredentialsProvider(AlibabaCloudCredentialsProvider provider) {
49+
return DefaultCredentialsProvider.userConfigurationProviders.add(provider);
50+
}
51+
52+
public static boolean removeCredentialsProvider(AlibabaCloudCredentialsProvider provider) {
53+
return DefaultCredentialsProvider.userConfigurationProviders.remove(provider);
54+
}
55+
56+
public static boolean containsCredentialsProvider(AlibabaCloudCredentialsProvider provider) {
57+
return DefaultCredentialsProvider.userConfigurationProviders.contains(provider);
58+
}
59+
60+
public static void clearCredentialsProvider() {
61+
DefaultCredentialsProvider.userConfigurationProviders.clear();
62+
}
63+
}

aliyun-java-sdk-core/src/main/java/com/aliyuncs/auth/ECSMetadataServiceCredentialsFetcher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
public class ECSMetadataServiceCredentialsFetcher {
2020
private static final String URL_IN_ECS_METADATA = "/latest/meta-data/ram/security-credentials/";
21-
private static final int DEFAULT_TIMEOUT_IN_MILLISECONDS = 5000;
21+
private static final int DEFAULT_TIMEOUT_IN_MILLISECONDS = 1000;
2222
private static final String ECS_METADAT_FETCH_ERROR_MSG = "Failed to get RAM session credentials from ECS metadata service.";
2323
private static final int DEFAULT_ECS_SESSION_TOKEN_DURATION_SECONDS = 3600 * 6;
2424
private URL credentialUrl;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.aliyuncs.auth;
2+
3+
import com.aliyuncs.exceptions.ClientException;
4+
import com.aliyuncs.utils.AuthUtils;
5+
6+
public class EnvironmentVariableCredentialsProvider implements AlibabaCloudCredentialsProvider {
7+
@Override
8+
public AlibabaCloudCredentials getCredentials() throws ClientException {
9+
if (!"default".equals(AuthUtils.getClientType())) {
10+
return null;
11+
}
12+
13+
String accessKeyId = AuthUtils.getEnvironmentAccessKeyId();
14+
String accessKeySecret = AuthUtils.getEnvironmentAccessKeySecret();
15+
if (accessKeyId == null || accessKeySecret == null) {
16+
return null;
17+
}
18+
if (accessKeyId.length() == 0) {
19+
throw new ClientException("Environment variable accessKeyId cannot be empty");
20+
}
21+
if (accessKeySecret.length() == 0) {
22+
throw new ClientException("Environment variable accessKeySecret cannot be empty");
23+
}
24+
return new BasicCredentials(accessKeyId, accessKeySecret);
25+
}
26+
}

aliyun-java-sdk-core/src/main/java/com/aliyuncs/auth/InstanceProfileCredentials.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
public class InstanceProfileCredentials extends BasicSessionCredentials {
99

1010
private final long expiration;
11-
private final double expireFact = 0.9;
12-
private final long refreshIntervalInMillSeconds = 10000; // 10 sec
11+
private final double expireFact = 0.95;
12+
private final long refreshIntervalInMillSeconds = 180000;
1313
private long lastFailedRefreshTime = 0;
1414

1515
public InstanceProfileCredentials(String accessKeyId, String accessKeySecret, String sessionToken,
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
package com.aliyuncs.auth;
2+
3+
import com.aliyuncs.exceptions.ClientException;
4+
import com.aliyuncs.utils.AuthUtils;
5+
import com.aliyuncs.utils.StringUtils;
6+
import org.ini4j.Profile;
7+
import org.ini4j.Wini;
8+
9+
import java.io.File;
10+
import java.io.IOException;
11+
import java.util.HashMap;
12+
import java.util.Map;
13+
14+
public class ProfileCredentialsProvider implements AlibabaCloudCredentialsProvider {
15+
private static volatile Wini ini;
16+
17+
private static Wini getIni(String filePath) throws IOException {
18+
if (null == ini) {
19+
synchronized (ProfileCredentialsProvider.class) {
20+
if (null == ini) {
21+
ini = new Wini(new File(filePath));
22+
}
23+
}
24+
}
25+
return ini;
26+
}
27+
28+
@Override
29+
public AlibabaCloudCredentials getCredentials() throws ClientException {
30+
String filePath = AuthUtils.getEnvironmentCredentialsFile();
31+
if (filePath == null) {
32+
filePath = AuthConstant.DEFAULT_CREDENTIALS_FILE_PATH;
33+
}
34+
if (filePath.length() == 0) {
35+
throw new ClientException("The specified credentials file is empty");
36+
}
37+
Wini ini;
38+
try {
39+
ini = getIni(filePath);
40+
} catch (IOException e) {
41+
return null;
42+
}
43+
Map<String, Map<String, String>> client = loadIni(ini);
44+
Map<String, String> clientConfig = client.get(AuthUtils.getClientType());
45+
if (clientConfig == null) {
46+
throw new ClientException("Client is not open in the specified credentials file");
47+
}
48+
CredentialsProviderFactory credentialsProviderFactory = new CredentialsProviderFactory();
49+
return createCredential(clientConfig, credentialsProviderFactory);
50+
}
51+
52+
private Map<String, Map<String, String>> loadIni(Wini ini) {
53+
Map<String, Map<String, String>> client = new HashMap<String, Map<String, String>>();
54+
boolean enable;
55+
for (Map.Entry<String, Profile.Section> clientType : ini.entrySet()) {
56+
enable = clientType.getValue().get(AuthConstant.INI_ENABLE, boolean.class);
57+
if (enable) {
58+
Map<String, String> clientConfig = new HashMap<String, String>();
59+
for (Map.Entry<String, String> enabledClient : clientType.getValue().entrySet()) {
60+
clientConfig.put(enabledClient.getKey(), enabledClient.getValue());
61+
}
62+
client.put(clientType.getKey(), clientConfig);
63+
}
64+
}
65+
return client;
66+
}
67+
68+
private AlibabaCloudCredentials createCredential(Map<String, String> clientConfig,
69+
CredentialsProviderFactory factory) throws ClientException {
70+
String configType = clientConfig.get(AuthConstant.INI_TYPE);
71+
if (StringUtils.isEmpty(configType)) {
72+
throw new ClientException("The configured client type is empty");
73+
}
74+
if (AuthConstant.INI_TYPE_ARN.equals(configType)) {
75+
return getSTSAssumeRoleSessionCredentials(clientConfig, factory);
76+
}
77+
if (AuthConstant.INI_TYPE_KEY_PAIR.equals(configType)) {
78+
return getSTSGetSessionAccessKeyCredentials(clientConfig, factory);
79+
}
80+
if (AuthConstant.INI_TYPE_RAM.equals(configType)) {
81+
return getInstanceProfileCredentials(clientConfig, factory);
82+
}
83+
String accessKeyId = clientConfig.get(AuthConstant.INI_ACCESS_KEY_ID);
84+
String accessKeySecret = clientConfig.get(AuthConstant.INI_ACCESS_KEY_IDSECRET);
85+
if (StringUtils.isEmpty(accessKeyId) || StringUtils.isEmpty(accessKeySecret)) {
86+
return null;
87+
}
88+
return new BasicCredentials(accessKeyId, accessKeySecret);
89+
}
90+
91+
private AlibabaCloudCredentials getSTSAssumeRoleSessionCredentials(Map<String, String> clientConfig,
92+
CredentialsProviderFactory factory)
93+
throws ClientException {
94+
String accessKeyId = clientConfig.get(AuthConstant.INI_ACCESS_KEY_ID);
95+
String accessKeySecret = clientConfig.get(AuthConstant.INI_ACCESS_KEY_IDSECRET);
96+
String roleSessionName = clientConfig.get(AuthConstant.INI_ROLE_SESSION_NAME);
97+
String roleArn = clientConfig.get(AuthConstant.INI_ROLE_ARN);
98+
String regionId = clientConfig.get(AuthConstant.DEFAULT_REGION);
99+
if (StringUtils.isEmpty(accessKeyId) || StringUtils.isEmpty(accessKeySecret)) {
100+
throw new ClientException("The configured access_key_id or access_key_secret is empty");
101+
}
102+
if (StringUtils.isEmpty(roleSessionName) || StringUtils.isEmpty(roleArn)) {
103+
throw new ClientException("The configured role_session_name or role_arn is empty");
104+
}
105+
STSAssumeRoleSessionCredentialsProvider provider =
106+
factory.createCredentialsProvider(new STSAssumeRoleSessionCredentialsProvider(accessKeyId,
107+
accessKeySecret, roleSessionName, roleArn, regionId));
108+
return provider.getCredentials();
109+
}
110+
111+
private AlibabaCloudCredentials getSTSGetSessionAccessKeyCredentials(Map<String, String> clientConfig,
112+
CredentialsProviderFactory factory)
113+
throws ClientException {
114+
String publicKeyId = clientConfig.get(AuthConstant.INI_PUBLIC_KEY_ID);
115+
String privateKeyFile = clientConfig.get(AuthConstant.INI_PRIVATE_KEY_FILE);
116+
if (StringUtils.isEmpty(privateKeyFile)) {
117+
throw new ClientException("The configured private_key_file is empty");
118+
}
119+
String privateKey = AuthUtils.getPrivateKey(privateKeyFile);
120+
if (StringUtils.isEmpty(publicKeyId) || StringUtils.isEmpty(privateKey)) {
121+
throw new ClientException("The configured public_key_id or private_key_file content is empty");
122+
}
123+
STSGetSessionAccessKeyCredentialsProvider provider =
124+
factory.createCredentialsProvider(new STSGetSessionAccessKeyCredentialsProvider(publicKeyId, privateKey));
125+
return provider.getCredentials();
126+
}
127+
128+
private AlibabaCloudCredentials getInstanceProfileCredentials(Map<String, String> clientConfig,
129+
CredentialsProviderFactory factory)
130+
throws ClientException {
131+
String roleName = clientConfig.get(AuthConstant.INI_ROLE_NAME);
132+
if (StringUtils.isEmpty(roleName)) {
133+
throw new ClientException("The configured role_name is empty");
134+
}
135+
InstanceProfileCredentialsProvider provider =
136+
factory.createCredentialsProvider(new InstanceProfileCredentialsProvider(roleName));
137+
return provider.getCredentials();
138+
}
139+
140+
141+
}

0 commit comments

Comments
 (0)