27
27
import java .net .URI ;
28
28
import java .net .URISyntaxException ;
29
29
import java .net .URL ;
30
+ import java .util .Base64 ;
30
31
import java .util .Collections ;
31
32
import java .util .HashMap ;
33
+ import java .util .concurrent .ExecutionException ;
32
34
33
35
@ ExtendWith (MockitoExtension .class )
34
36
@ TestInstance (TestInstance .Lifecycle .PER_CLASS )
@@ -294,4 +296,44 @@ void testExecuteOAuth_Failure() throws SerializeException,
294
296
295
297
assertThrows (MsalException .class , request ::executeTokenRequest );
296
298
}
299
+
300
+ @ Test
301
+ void testBase64UrlEncoding () throws MalformedURLException , ExecutionException , InterruptedException {
302
+ DefaultHttpClient httpClientMock = mock (DefaultHttpClient .class );
303
+ ConfidentialClientApplication cca =
304
+ ConfidentialClientApplication .builder ("clientId" , ClientCredentialFactory .createFromSecret ("password" ))
305
+ .authority ("https://login.microsoftonline.com/tenant/" )
306
+ .instanceDiscovery (false )
307
+ .validateAuthority (false )
308
+ .httpClient (httpClientMock )
309
+ .build ();
310
+
311
+ //ID token payloads are parsed to get certain info to create Account and AccountCacheEntity objects, and the library must decode them using a Base64URL decoder.
312
+ HashMap <String , String > tokenParameters = new HashMap <>();
313
+ tokenParameters .put ("preferred_username" , "~nameWith~specialChars" );
314
+ String encodedIDToken = TestHelper .createIdToken (tokenParameters );
315
+ try {
316
+ //TestHelper.createIdToken() should use Base64URL encoding, so first we prove that the encoded token it produces cannot be decoded with Base64 decoder
317
+ Base64 .getDecoder ().decode (encodedIDToken .split ("\\ ." )[1 ]);
318
+
319
+ fail ("IllegalArgumentException was expected but not thrown." );
320
+ } catch (IllegalArgumentException e ) {
321
+ //Encoded token should have some "-" characters in it
322
+ assertTrue (e .getMessage ().contains ("Illegal base64 character 2d" ));
323
+ }
324
+
325
+ //Now, send that encoded token through the library's token request flow, which will decode it using a Base64URL decoder
326
+ HashMap <String , String > responseParameters = new HashMap <>();
327
+ responseParameters .put ("id_token" , encodedIDToken );
328
+ responseParameters .put ("access_token" , "token" );
329
+ TestHelper .createTokenRequestMock (httpClientMock , TestHelper .getSuccessfulTokenResponse (responseParameters ), 200 );
330
+
331
+ OnBehalfOfParameters parameters = OnBehalfOfParameters .builder (Collections .singleton ("someScopes" ), new UserAssertion (TestHelper .signedAssertion )).build ();
332
+ IAuthenticationResult result = cca .acquireToken (parameters ).get ();
333
+
334
+ //Ensure that the name was successfully parsed out of the encoded ID token
335
+ assertNotNull (result .idToken ());
336
+ assertNotNull (result .account ());
337
+ assertEquals ("~nameWith~specialChars" , result .account ().username ());
338
+ }
297
339
}
0 commit comments