Skip to content

Commit 1510e6a

Browse files
Merge pull request #5484 from AzureAD/2130019_fix_cache_cred_lookup
2130019. Fix cache credential look-up.
2 parents fd945e6 + e4d8ed5 commit 1510e6a

File tree

3 files changed

+151
-10
lines changed

3 files changed

+151
-10
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "Fix cache credential look-up (#5484)",
4+
"packageName": "@azure/msal-common",
5+
"email": "kshabelko@microsoft.com",
6+
"dependentChangeType": "patch"
7+
}

lib/msal-common/src/cache/entities/CredentialEntity.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -108,17 +108,16 @@ export class CredentialEntity {
108108
* @param key
109109
*/
110110
static getCredentialType(key: string): string {
111-
// First keyword search will match all "AccessToken" and "AccessToken_With_AuthScheme" credentials
112-
if (key.indexOf(CredentialType.ACCESS_TOKEN.toLowerCase()) !== -1) {
113-
// Perform second search to differentiate between "AccessToken" and "AccessToken_With_AuthScheme" credential types
114-
if (key.indexOf(CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME.toLowerCase()) !== -1) {
115-
return CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME;
111+
const separator = Separators.CACHE_KEY_SEPARATOR;
112+
// Match host names like "login.microsoftonline.com", "https://accounts.google.com:4000", etc.
113+
const domainRe = "(https?:\\/\\/)?([\\w-]+\\.)*([\\w-]{1,63})(\\.(\\w{2,3}))(\\:[0-9]{4,5})?";
114+
115+
for (const credKey of Object.keys(CredentialType)) {
116+
const credVal = CredentialType[credKey].toLowerCase();
117+
// Verify credential type is preceded by a valid host name (environment)
118+
if (key.toLowerCase().search(`(?<=${separator}${domainRe})${separator}${credVal}${separator}`) !== -1) {
119+
return CredentialType[credKey];
116120
}
117-
return CredentialType.ACCESS_TOKEN;
118-
} else if (key.indexOf(CredentialType.ID_TOKEN.toLowerCase()) !== -1) {
119-
return CredentialType.ID_TOKEN;
120-
} else if (key.indexOf(CredentialType.REFRESH_TOKEN.toLowerCase()) !== -1) {
121-
return CredentialType.REFRESH_TOKEN;
122121
}
123122

124123
return Constants.NOT_DEFINED;
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
import { AccessTokenEntity, Constants, CredentialEntity, CredentialType } from "../../../src";
2+
import {TEST_CONFIG, TEST_DATA_CLIENT_INFO} from "../../test_kit/StringConstants";
3+
4+
describe("CredentialEntity.ts Unit Tests", () => {
5+
6+
const clientId = TEST_CONFIG.MSAL_CLIENT_ID;
7+
const homeAccountId = `${TEST_DATA_CLIENT_INFO.TEST_UID}.${TEST_DATA_CLIENT_INFO.TEST_UTID}`;
8+
9+
describe("Get credential type", () => {
10+
it("GUID homeAccountId - Is access token", () => {
11+
const atEntity = new AccessTokenEntity();
12+
Object.assign(atEntity, {
13+
homeAccountId,
14+
environment: "login.microsoftonline.com",
15+
credentialType: "AccessToken",
16+
clientId: "mock_client_id",
17+
secret: "an access token sample",
18+
realm: "microsoft",
19+
target: "scope6 scope7",
20+
cachedAt: "1000",
21+
expiresOn: "4600",
22+
extendedExpiresOn: "4600",
23+
tokenType: "Bearer"
24+
});
25+
26+
const atKey = atEntity.generateCredentialKey();
27+
28+
expect(CredentialEntity.getCredentialType(atKey)).toEqual(CredentialType.ACCESS_TOKEN);
29+
});
30+
31+
it("String homeAccountId - Is access token", () => {
32+
const atEntity = new AccessTokenEntity();
33+
Object.assign(atEntity, {
34+
homeAccountId: "homeAccountId",
35+
environment: "login.microsoftonline.com",
36+
credentialType: "AccessToken",
37+
clientId: "mock_client_id",
38+
secret: "an access token sample",
39+
realm: "microsoft",
40+
target: "scope6 scope7",
41+
cachedAt: "1000",
42+
expiresOn: "4600",
43+
extendedExpiresOn: "4600",
44+
tokenType: "Bearer"
45+
});
46+
47+
const atKey = atEntity.generateCredentialKey();
48+
49+
expect(CredentialEntity.getCredentialType(atKey)).toEqual(CredentialType.ACCESS_TOKEN);
50+
});
51+
52+
it("Missing homeAccountId - is access token", () => {
53+
const atEntity = new AccessTokenEntity();
54+
Object.assign(atEntity, {
55+
homeAccountId: Constants.EMPTY_STRING,
56+
environment: "login.microsoftonline.com",
57+
credentialType: "AccessToken",
58+
clientId: "mock_client_id",
59+
secret: "an access token sample",
60+
realm: "microsoft",
61+
target: "scope6 scope7",
62+
cachedAt: "1000",
63+
expiresOn: "4600",
64+
extendedExpiresOn: "4600",
65+
tokenType: "Bearer"
66+
});
67+
68+
const atKey = atEntity.generateCredentialKey();
69+
70+
expect(CredentialEntity.getCredentialType(atKey)).toEqual(CredentialType.ACCESS_TOKEN);
71+
});
72+
73+
it("Host name with prefix and port - Is access token", () => {
74+
const atEntity = new AccessTokenEntity();
75+
Object.assign(atEntity, {
76+
homeAccountId,
77+
environment: "https://login.microsoftonline.com:40000",
78+
credentialType: "AccessToken",
79+
clientId: "mock_client_id",
80+
secret: "an access token sample",
81+
realm: "microsoft",
82+
target: "scope6 scope7",
83+
cachedAt: "1000",
84+
expiresOn: "4600",
85+
extendedExpiresOn: "4600",
86+
tokenType: "Bearer"
87+
});
88+
89+
const atKey = atEntity.generateCredentialKey();
90+
91+
expect(CredentialEntity.getCredentialType(atKey)).toEqual(CredentialType.ACCESS_TOKEN);
92+
});
93+
94+
it("Host name with multiple TLDs - Is access token", () => {
95+
const atEntity = new AccessTokenEntity();
96+
Object.assign(atEntity, {
97+
homeAccountId,
98+
environment: "login.microsoftonline.us.com:40000",
99+
credentialType: "AccessToken",
100+
clientId: "mock_client_id",
101+
secret: "an access token sample",
102+
realm: "microsoft",
103+
target: "scope6 scope7",
104+
cachedAt: "1000",
105+
expiresOn: "4600",
106+
extendedExpiresOn: "4600",
107+
tokenType: "Bearer"
108+
});
109+
110+
const atKey = atEntity.generateCredentialKey();
111+
112+
expect(CredentialEntity.getCredentialType(atKey)).toEqual(CredentialType.ACCESS_TOKEN);
113+
});
114+
115+
it("Metadata key - empty result", () => {
116+
const key = `authority-metadata-${clientId}-login.microsoftonline.com`;
117+
expect(CredentialEntity.getCredentialType(key)).toEqual(Constants.NOT_DEFINED);
118+
});
119+
120+
it("Partial workflow match - empty result", () => {
121+
const key = `${homeAccountId}-accessTokenWorkflow-login.microsoftonline.com-someothertoken-${clientId}---`;
122+
expect(CredentialEntity.getCredentialType(key)).toEqual(Constants.NOT_DEFINED);
123+
});
124+
125+
it("Invalid host name - empty result", () => {
126+
const key = `${homeAccountId}-login.microsoftonline-accessToken-${clientId}---`;
127+
expect(CredentialEntity.getCredentialType(key)).toEqual(Constants.NOT_DEFINED);
128+
});
129+
130+
it("Empty host name - empty result", () => {
131+
const key = `${homeAccountId}--accessToken-${clientId}---`;
132+
expect(CredentialEntity.getCredentialType(key)).toEqual(Constants.NOT_DEFINED);
133+
});
134+
})
135+
});

0 commit comments

Comments
 (0)