Skip to content

Commit fb0f51e

Browse files
committed
Add test for mixed and overridden credentials
1 parent f702ca9 commit fb0f51e

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

msal4j-sdk/src/test/java/com/microsoft/aad/msal4j/ClientCredentialTest.java

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,81 @@ void OnBehalfOf_TenantOverride() throws Exception {
107107
assertNotEquals(resultAppLevelTenant.accessToken(), resultRequestLevelTenant.accessToken());
108108
verify(httpClientMock, times(2)).send(any());
109109
}
110+
111+
@Test
112+
void testCredentialPrecedenceAndMixing() throws Exception {
113+
DefaultHttpClient httpClientMock = mock(DefaultHttpClient.class);
114+
115+
// Create different credential types for testing
116+
IClientCredential appLevelCredential = ClientCredentialFactory.createFromSecret("appLevelSecret");
117+
IClientCredential requestLevelSecret = ClientCredentialFactory.createFromSecret("requestLevelSecret");
118+
String assertionValue = "test_assertion_value";
119+
IClientCredential requestLevelAssertion = ClientCredentialFactory.createFromClientAssertion(assertionValue);
120+
121+
// Create the application with the app-level credential
122+
ConfidentialClientApplication cca =
123+
ConfidentialClientApplication.builder("clientId", appLevelCredential)
124+
.authority("https://login.microsoftonline.com/tenant")
125+
.instanceDiscovery(false)
126+
.validateAuthority(false)
127+
.httpClient(httpClientMock)
128+
.build();
129+
130+
// Set up the mock to check which credential is being used
131+
when(httpClientMock.send(any(HttpRequest.class))).thenAnswer(invocation -> {
132+
HttpRequest request = invocation.getArgument(0);
133+
String requestBody = request.body();
134+
135+
// Check which credential type is included in the request and return a matching token
136+
if (requestBody.contains("client_secret=requestLevelSecret")) {
137+
HashMap<String, String> responseParams = new HashMap<>();
138+
responseParams.put("access_token", "request_secret_token");
139+
return TestHelper.expectedResponse(HttpStatus.HTTP_OK,
140+
TestHelper.getSuccessfulTokenResponse(responseParams));
141+
} else if (requestBody.contains("client_secret=appLevelSecret")) {
142+
HashMap<String, String> responseParams = new HashMap<>();
143+
responseParams.put("access_token", "app_secret_token");
144+
return TestHelper.expectedResponse(HttpStatus.HTTP_OK,
145+
TestHelper.getSuccessfulTokenResponse(responseParams));
146+
} else if (requestBody.contains("client_assertion=" + assertionValue)) {
147+
HashMap<String, String> responseParams = new HashMap<>();
148+
responseParams.put("access_token", "assertion_token");
149+
return TestHelper.expectedResponse(HttpStatus.HTTP_OK,
150+
TestHelper.getSuccessfulTokenResponse(responseParams));
151+
}
152+
return null;
153+
});
154+
155+
// Test 1: Request with same credential type (secret) at request level
156+
ClientCredentialParameters parametersWithRequestSecret =
157+
ClientCredentialParameters.builder(Collections.singleton("scope"))
158+
.clientCredential(requestLevelSecret)
159+
.skipCache(true)
160+
.build();
161+
162+
IAuthenticationResult result1 = cca.acquireToken(parametersWithRequestSecret).get();
163+
assertEquals("request_secret_token", result1.accessToken(),
164+
"Request-level secret should be used when provided");
165+
166+
// Test 2: Request with different credential type (assertion) at request level
167+
ClientCredentialParameters parametersWithAssertion =
168+
ClientCredentialParameters.builder(Collections.singleton("scope"))
169+
.clientCredential(requestLevelAssertion)
170+
.skipCache(true)
171+
.build();
172+
173+
IAuthenticationResult result2 = cca.acquireToken(parametersWithAssertion).get();
174+
assertEquals("assertion_token", result2.accessToken(),
175+
"Request-level assertion should be used when provided");
176+
177+
// Test 3: Request without credential specified should fall back to app-level
178+
ClientCredentialParameters parametersWithoutCredential =
179+
ClientCredentialParameters.builder(Collections.singleton("scope"))
180+
.skipCache(true)
181+
.build();
182+
183+
IAuthenticationResult result3 = cca.acquireToken(parametersWithoutCredential).get();
184+
assertEquals("app_secret_token", result3.accessToken(),
185+
"App-level credential should be used when request-level credential is not provided");
186+
}
110187
}

0 commit comments

Comments
 (0)