33
44package com .microsoft .aad .msal4j ;
55
6+ import com .nimbusds .jose .JOSEException ;
67import com .nimbusds .jose .JWSAlgorithm ;
78import com .nimbusds .jose .JWSHeader ;
89import com .nimbusds .jose .crypto .RSASSASigner ;
910import com .nimbusds .jose .util .Base64 ;
1011import com .nimbusds .jose .util .Base64URL ;
1112import com .nimbusds .jwt .JWTClaimsSet ;
1213import com .nimbusds .jwt .SignedJWT ;
14+ import com .nimbusds .oauth2 .sdk .auth .JWTAuthentication ;
1315import com .nimbusds .oauth2 .sdk .auth .PrivateKeyJWT ;
16+ import org .easymock .Capture ;
1417import org .easymock .EasyMock ;
1518import org .powermock .api .easymock .PowerMock ;
1619import org .powermock .core .classloader .annotations .PowerMockIgnore ;
2225
2326import java .io .IOException ;
2427import java .net .URI ;
28+ import java .net .URLEncoder ;
2529import java .security .*;
2630import java .security .cert .CertificateException ;
2731import java .util .*;
2832import java .util .concurrent .Future ;
2933
30- import static org .testng . Assert . assertFalse ;
31- import static org .testng .Assert .assertNotNull ;
34+ import static org .easymock . EasyMock .* ;
35+ import static org .testng .Assert .* ;
3236
3337@ PowerMockIgnore ({"javax.net.ssl.*" })
3438@ PrepareForTest ({ConfidentialClientApplication .class ,
@@ -206,29 +210,7 @@ private ClientAssertion buildShortJwt(String clientId,
206210
207211 @ Test
208212 public void testClientAssertion_noException () throws Exception {
209-
210- IClientCertificate certificate = CertificateHelper .getClientCertificate ();
211-
212- final ClientCertificate credential = (ClientCertificate ) certificate ;
213-
214- final JWTClaimsSet claimsSet = new JWTClaimsSet .Builder ()
215- .issuer ("issuer" )
216- .subject ("subject" )
217- .build ();
218-
219- SignedJWT jwt ;
220- JWSHeader .Builder builder = new JWSHeader .Builder (JWSAlgorithm .RS256 );
221-
222- List <Base64 > certs = new ArrayList <>();
223- for (String cert : credential .getEncodedPublicKeyCertificateChain ()) {
224- certs .add (new Base64 (cert ));
225- }
226- builder .x509CertChain (certs );
227-
228- jwt = new SignedJWT (builder .build (), claimsSet );
229- final RSASSASigner signer = new RSASSASigner (credential .privateKey ());
230-
231- jwt .sign (signer );
213+ SignedJWT jwt = createClientAssertion ("issuer" );
232214
233215 ClientAssertion clientAssertion = new ClientAssertion (jwt .serialize ());
234216
@@ -245,14 +227,84 @@ public void testClientAssertion_noException() throws Exception{
245227
246228 }
247229
230+ @ Test
231+ public void testClientAssertion_acquireToken () throws Exception {
232+ SignedJWT jwt = createClientAssertion ("issuer" );
233+
234+ ClientAssertion clientAssertion = new ClientAssertion (jwt .serialize ());
235+ ConfidentialClientApplication app = ConfidentialClientApplication
236+ .builder (TestConfiguration .AAD_CLIENT_ID , ClientCredentialFactory .createFromClientAssertion (clientAssertion .assertion ()))
237+ .authority (TestConfiguration .AAD_TENANT_ENDPOINT )
238+ .build ();
239+
240+ String scope = "requestedScope" ;
241+ ClientCredentialRequest clientCredentialRequest = getClientCredentialRequest (app , scope );
242+
243+ IHttpClient httpClientMock = EasyMock .mock (IHttpClient .class );
244+ Capture <HttpRequest > captureSingleArgument = newCapture ();
245+ expect (httpClientMock .send (capture (captureSingleArgument ))).andReturn (new HttpResponse ());
246+ EasyMock .replay (httpClientMock );
247+
248+ TokenRequestExecutor tokenRequestExecutor = new TokenRequestExecutor (app .authenticationAuthority , clientCredentialRequest , mockedServiceBundle (httpClientMock ));
249+ try {
250+ tokenRequestExecutor .executeTokenRequest ();
251+ } catch (Exception e ) {
252+ //Ignored, we only want to check the request that was send.
253+ }
254+ HttpRequest value = captureSingleArgument .getValue ();
255+ String body = value .body ();
256+ Assert .assertTrue (body .contains ("grant_type=client_credentials" ));
257+ Assert .assertTrue (body .contains ("client_assertion=" + clientAssertion .assertion ()));
258+ Assert .assertTrue (body .contains ("client_assertion_type=" + URLEncoder .encode (JWTAuthentication .CLIENT_ASSERTION_TYPE , "utf-8" )));
259+ Assert .assertTrue (body .contains ("scope=" + URLEncoder .encode ("openid profile offline_access " + scope , "utf-8" )));
260+ Assert .assertTrue (body .contains ("client_id=" + TestConfiguration .AAD_CLIENT_ID ));
261+ }
262+
263+ private ServiceBundle mockedServiceBundle (IHttpClient httpClientMock ) {
264+ ServiceBundle serviceBundle = new ServiceBundle (
265+ null ,
266+ httpClientMock ,
267+ new TelemetryManager (null , false ));
268+ return serviceBundle ;
269+ }
270+
271+ private ClientCredentialRequest getClientCredentialRequest (ConfidentialClientApplication app , String scope ) {
272+ Set <String > scopes = new HashSet <>();
273+ scopes .add (scope );
274+ ClientCredentialParameters clientCredentials = ClientCredentialParameters .builder (scopes ).tenant (IdToken .TENANT_IDENTIFIER ).build ();
275+ RequestContext requestContext = new RequestContext (
276+ app ,
277+ PublicApi .ACQUIRE_TOKEN_FOR_CLIENT ,
278+ clientCredentials );
279+
280+ ClientCredentialRequest clientCredentialRequest =
281+ new ClientCredentialRequest (
282+ clientCredentials ,
283+ app ,
284+ requestContext );
285+ return clientCredentialRequest ;
286+ }
287+
248288 @ Test (expectedExceptions = MsalClientException .class )
249289 public void testClientAssertion_throwsException () throws Exception {
290+ SignedJWT jwt = createClientAssertion (null );
291+
292+ ClientAssertion clientAssertion = new ClientAssertion (jwt .serialize ());
293+
294+ IClientCredential iClientCredential = ClientCredentialFactory .createFromClientAssertion (
295+ clientAssertion .assertion ());
250296
297+ ConfidentialClientApplication .builder (TestConfiguration .AAD_CLIENT_ID , iClientCredential ).authority (TestConfiguration .AAD_TENANT_ENDPOINT ).build ();
298+
299+ }
300+
301+ private SignedJWT createClientAssertion (String issuer ) throws KeyStoreException , IOException , NoSuchAlgorithmException , CertificateException , UnrecoverableKeyException , NoSuchProviderException , JOSEException {
251302 IClientCertificate certificate = CertificateHelper .getClientCertificate ();
303+
252304 final ClientCertificate credential = (ClientCertificate ) certificate ;
253305
254306 final JWTClaimsSet claimsSet = new JWTClaimsSet .Builder ()
255- .issuer (null )
307+ .issuer (issuer )
256308 .subject ("subject" )
257309 .build ();
258310
@@ -269,15 +321,7 @@ public void testClientAssertion_throwsException() throws Exception{
269321 final RSASSASigner signer = new RSASSASigner (credential .privateKey ());
270322
271323 jwt .sign (signer );
272-
273- ClientAssertion clientAssertion = new ClientAssertion (jwt .serialize ());
274-
275- IClientCredential iClientCredential = ClientCredentialFactory .createFromClientAssertion (
276- clientAssertion .assertion ());
277-
278- ConfidentialClientApplication .builder (TestConfiguration .AAD_CLIENT_ID , iClientCredential ).authority (TestConfiguration .AAD_TENANT_ENDPOINT ).build ();
279-
324+ return jwt ;
280325 }
281326
282-
283327}
0 commit comments