Skip to content

Commit 00dc13f

Browse files
yndu13sdk-team
authored andcommitted
feat: resolve sensitive value in model && deprecate regionId
1 parent ddadf54 commit 00dc13f

File tree

4 files changed

+142
-15
lines changed

4 files changed

+142
-15
lines changed

src/main/java/com/aliyun/credentials/models/CredentialModel.java

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import com.aliyun.credentials.AlibabaCloudCredentials;
55
import com.aliyun.credentials.api.ICredentials;
6+
import com.aliyun.credentials.utils.StringUtils;
67
import com.aliyun.tea.*;
78

89
public class CredentialModel extends TeaModel implements AlibabaCloudCredentials, ICredentials {
@@ -87,9 +88,47 @@ public String getProviderName() {
8788
return providerName;
8889
}
8990

91+
/**
92+
* 对敏感信息进行模糊处理,保留首尾字符
93+
*
94+
* @param value 需要模糊处理的字符串
95+
* @return 模糊处理后的字符串
96+
*/
97+
private String maskSensitiveValue(String value) {
98+
if (value == null || value.length() <= 6) {
99+
return "****";
100+
}
101+
102+
int length = value.length();
103+
int prefixLength = Math.min(3, length / 4);
104+
int suffixLength = Math.min(3, length / 4);
105+
106+
String prefix = value.substring(0, prefixLength);
107+
String suffix = value.substring(length - suffixLength);
108+
109+
StringBuilder masked = new StringBuilder();
110+
masked.append(prefix);
111+
for (int i = 0; i < length - prefixLength - suffixLength; i++) {
112+
masked.append("*");
113+
}
114+
masked.append(suffix);
115+
116+
return masked.toString();
117+
}
118+
90119
@Override
91120
public String toString() {
92-
return String.format("Credential(accessKeyId=%s, accessKeySecret=%s, securityToken=%s, providerName=%s, expiration=%s)", accessKeyId, accessKeySecret, securityToken, providerName, expiration);
121+
if (!StringUtils.isEmpty(bearerToken)) {
122+
return String.format("Credential(bearerToken=%s, providerName=%s)",
123+
maskSensitiveValue(bearerToken),
124+
providerName);
125+
}
126+
return String.format("Credential(accessKeyId=%s, accessKeySecret=%s, securityToken=%s, providerName=%s, expiration=%s)",
127+
maskSensitiveValue(accessKeyId),
128+
maskSensitiveValue(accessKeySecret),
129+
maskSensitiveValue(securityToken),
130+
providerName,
131+
expiration);
93132
}
94133

95134
public static final class Builder {
@@ -141,5 +180,4 @@ public CredentialModel build() {
141180
}
142181
}
143182

144-
}
145-
183+
}

src/main/java/com/aliyun/credentials/provider/OIDCRoleArnCredentialProvider.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ public interface Builder extends SessionCredentialsProvider.Builder<OIDCRoleArnC
347347

348348
Builder oidcTokenFilePath(String oidcTokenFilePath);
349349

350+
@Deprecated
350351
Builder regionId(String regionId);
351352

352353
Builder policy(String policy);
@@ -406,6 +407,7 @@ public Builder oidcTokenFilePath(String oidcTokenFilePath) {
406407
return this;
407408
}
408409

410+
@Deprecated
409411
public Builder regionId(String regionId) {
410412
this.regionId = regionId;
411413
return this;

src/main/java/com/aliyun/credentials/provider/RamRoleArnCredentialProvider.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ public interface Builder extends SessionCredentialsProvider.Builder<RamRoleArnCr
341341

342342
Builder roleArn(String roleArn);
343343

344+
@Deprecated
344345
Builder regionId(String regionId);
345346

346347
Builder policy(String policy);
@@ -403,6 +404,7 @@ public Builder roleArn(String roleArn) {
403404
return this;
404405
}
405406

407+
@Deprecated
406408
public Builder regionId(String regionId) {
407409
this.regionId = regionId;
408410
return this;

src/test/java/com/aliyun/credentials/models/CredentialModelTest.java

Lines changed: 97 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ public class CredentialModelTest {
77
@Test
88
public void builderTest() {
99
CredentialModel model = CredentialModel.builder()
10-
.accessKeyId("akid")
11-
.accessKeySecret("aksecret")
12-
.securityToken("securityToken")
13-
.bearerToken("bearertoken")
14-
.expiration(100L)
15-
.type("type")
16-
.build();
10+
.accessKeyId("akid")
11+
.accessKeySecret("aksecret")
12+
.securityToken("securityToken")
13+
.bearerToken("bearertoken")
14+
.expiration(100L)
15+
.type("type")
16+
.build();
1717
Assert.assertEquals("akid", model.getAccessKeyId());
1818
Assert.assertEquals("aksecret", model.getAccessKeySecret());
1919
Assert.assertEquals("securityToken", model.getSecurityToken());
@@ -26,10 +26,10 @@ public void builderTest() {
2626
public void setGetTest() {
2727
CredentialModel model = CredentialModel.builder().build();
2828
model.setAccessKeyId("akid")
29-
.setAccessKeySecret("aksecret")
30-
.setSecurityToken("securityToken")
31-
.setBearerToken("bearertoken")
32-
.setType("type");
29+
.setAccessKeySecret("aksecret")
30+
.setSecurityToken("securityToken")
31+
.setBearerToken("bearertoken")
32+
.setType("type");
3333
Assert.assertEquals("akid", model.getAccessKeyId());
3434
Assert.assertEquals("aksecret", model.getAccessKeySecret());
3535
Assert.assertEquals("securityToken", model.getSecurityToken());
@@ -38,4 +38,89 @@ public void setGetTest() {
3838
// Assert.assertEquals(100L, model.getExpiration());
3939
Assert.assertEquals("type", model.getType());
4040
}
41-
}
41+
42+
@Test
43+
public void toStringWithBearerTokenTest() {
44+
CredentialModel model = CredentialModel.builder()
45+
.bearerToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9")
46+
.providerName("testProvider")
47+
.build();
48+
49+
String result = model.toString();
50+
Assert.assertTrue("toString should contain bearerToken format", result.startsWith("Credential(bearerToken="));
51+
Assert.assertTrue("toString should contain masked bearerToken", result.contains("eyJ******************************CJ9"));
52+
Assert.assertTrue("toString should contain providerName", result.contains("providerName=testProvider"));
53+
Assert.assertFalse("toString should not contain accessKeyId when bearerToken exists", result.contains("accessKeyId"));
54+
}
55+
56+
@Test
57+
public void toStringWithoutBearerTokenTest() {
58+
CredentialModel model = CredentialModel.builder()
59+
.accessKeyId("LTAI4G3jVkK2DYajXXXXXXXX")
60+
.accessKeySecret("abcdefghijklmnopqrstuvwxyz")
61+
.securityToken("STS.NUCJMaR7bKxD5A2rDq6")
62+
.providerName("testProvider")
63+
.expiration(1234567890L)
64+
.build();
65+
66+
String result = model.toString();
67+
Assert.assertTrue("toString should contain accessKeyId format", result.startsWith("Credential(accessKeyId="));
68+
Assert.assertTrue("toString should contain masked accessKeyId", result.contains("LTA******************XXX"));
69+
Assert.assertTrue("toString should contain masked accessKeySecret", result.contains("abc********************xyz"));
70+
Assert.assertTrue("toString should contain masked securityToken", result.contains("STS*****************Dq6"));
71+
Assert.assertTrue("toString should contain providerName", result.contains("providerName=testProvider"));
72+
Assert.assertTrue("toString should contain expiration", result.contains("expiration=1234567890"));
73+
}
74+
75+
@Test
76+
public void toStringWithEmptyBearerTokenTest() {
77+
CredentialModel model = CredentialModel.builder()
78+
.accessKeyId("testAccessKeyId")
79+
.accessKeySecret("testAccessKeySecret")
80+
.securityToken("testSecurityToken")
81+
.bearerToken("") // 空字符串
82+
.providerName("testProvider")
83+
.expiration(9876543210L)
84+
.build();
85+
86+
String result = model.toString();
87+
// 空字符串应该被认为是空,所以应该使用accessKey格式
88+
Assert.assertTrue("toString should contain accessKeyId format when bearerToken is empty", result.startsWith("Credential(accessKeyId="));
89+
Assert.assertTrue("toString should contain masked accessKeyId", result.contains("tes*********yId"));
90+
Assert.assertFalse("toString should not contain bearerToken when it's empty", result.contains("bearerToken"));
91+
}
92+
93+
@Test
94+
public void toStringWithNullBearerTokenTest() {
95+
CredentialModel model = CredentialModel.builder()
96+
.accessKeyId("testAccessKeyId")
97+
.accessKeySecret("testAccessKeySecret")
98+
.securityToken("testSecurityToken")
99+
.bearerToken(null) // null值
100+
.providerName("testProvider")
101+
.expiration(9876543210L)
102+
.build();
103+
104+
String result = model.toString();
105+
// null应该被认为是空,所以应该使用accessKey格式
106+
Assert.assertTrue("toString should contain accessKeyId format when bearerToken is null", result.startsWith("Credential(accessKeyId="));
107+
Assert.assertTrue("toString should contain masked accessKeyId", result.contains("tes*********yId"));
108+
Assert.assertFalse("toString should not contain bearerToken when it's null", result.contains("bearerToken"));
109+
}
110+
111+
@Test
112+
public void toStringMaskingShortValuesTest() {
113+
CredentialModel model = CredentialModel.builder()
114+
.accessKeyId("short") // 短字符串
115+
.accessKeySecret("abc") // 很短的字符串
116+
.securityToken(null) // null值
117+
.providerName("testProvider")
118+
.expiration(1111111111L)
119+
.build();
120+
121+
String result = model.toString();
122+
Assert.assertTrue("toString should mask short accessKeyId with ****", result.contains("accessKeyId=****"));
123+
Assert.assertTrue("toString should mask short accessKeySecret with ****", result.contains("accessKeySecret=****"));
124+
Assert.assertTrue("toString should mask null securityToken with ****", result.contains("securityToken=****"));
125+
}
126+
}

0 commit comments

Comments
 (0)