From 7daad64fcc7256d28a1ff13cac79e17433a1aada Mon Sep 17 00:00:00 2001 From: Petro Somka Date: Tue, 19 Feb 2019 15:43:08 -0800 Subject: [PATCH 1/4] device code flow --- .../aad/msal4j/AcquireDeviceCodeCallable.java | 47 ---------- .../AcquireTokenDeviceCodeFlowSupplier.java | 71 +++++++++++++++ ...allable.java => AcquireTokenSupplier.java} | 82 ++--------------- .../aad/msal4j/ClientApplicationBase.java | 25 +----- .../microsoft/aad/msal4j/MsalSupplier.java | 89 +++++++++++++++++++ .../aad/msal4j/PublicClientApplication.java | 89 +++++++------------ src/samples/public-client/DeviceCodeFlow.java | 34 ++++--- .../public-client/IntegratedAuthFlow.java | 2 +- ...owAsync.java => UsernamePasswordFlow.java} | 4 +- .../aad/msal4j/DeviceCodeFlowTest.java | 48 +++++----- 10 files changed, 255 insertions(+), 236 deletions(-) delete mode 100644 src/main/java/com/microsoft/aad/msal4j/AcquireDeviceCodeCallable.java create mode 100644 src/main/java/com/microsoft/aad/msal4j/AcquireTokenDeviceCodeFlowSupplier.java rename src/main/java/com/microsoft/aad/msal4j/{AcquireTokenCallable.java => AcquireTokenSupplier.java} (60%) create mode 100644 src/main/java/com/microsoft/aad/msal4j/MsalSupplier.java rename src/samples/public-client/{UsernamePasswordFlowAsync.java => UsernamePasswordFlow.java} (97%) diff --git a/src/main/java/com/microsoft/aad/msal4j/AcquireDeviceCodeCallable.java b/src/main/java/com/microsoft/aad/msal4j/AcquireDeviceCodeCallable.java deleted file mode 100644 index 194e154f..00000000 --- a/src/main/java/com/microsoft/aad/msal4j/AcquireDeviceCodeCallable.java +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package com.microsoft.aad.msal4j; - -import java.util.Set; - -class AcquireDeviceCodeCallable extends MsalCallable { - private String clientId; - private String scopes; - - AcquireDeviceCodeCallable(PublicClientApplication clientApplication, - String clientId, Set scopes) { - super(clientApplication); - this.headers = new ClientDataHttpHeaders(clientApplication.getCorrelationId()); - this.clientId = clientId; - this.scopes = String.join(" ", scopes); - } - - DeviceCode execute() throws Exception { - clientApplication.authenticationAuthority.doInstanceDiscovery(clientApplication.isValidateAuthority(), - headers.getReadonlyHeaderMap(), clientApplication.getProxy(), clientApplication.getSslSocketFactory()); - return DeviceCodeRequest.execute(clientApplication.authenticationAuthority.getDeviceCodeEndpoint(), - clientId, scopes, headers.getReadonlyHeaderMap(), clientApplication.getProxy(), - clientApplication.getSslSocketFactory()); - } -} diff --git a/src/main/java/com/microsoft/aad/msal4j/AcquireTokenDeviceCodeFlowSupplier.java b/src/main/java/com/microsoft/aad/msal4j/AcquireTokenDeviceCodeFlowSupplier.java new file mode 100644 index 00000000..692d8454 --- /dev/null +++ b/src/main/java/com/microsoft/aad/msal4j/AcquireTokenDeviceCodeFlowSupplier.java @@ -0,0 +1,71 @@ +package com.microsoft.aad.msal4j; + +import com.nimbusds.oauth2.sdk.auth.ClientAuthentication; + +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; + +import static com.microsoft.aad.msal4j.AdalErrorCode.AUTHORIZATION_PENDING; + +public class AcquireTokenDeviceCodeFlowSupplier extends MsalSupplier { + + private ClientAuthentication clientAuth; + private String scopes; + private Consumer deviceCodeConsumer; + private AtomicReference> futureReference; + + AcquireTokenDeviceCodeFlowSupplier(PublicClientApplication clientApplication, ClientAuthentication clientAuth, + Set scopes, Consumer deviceCodeConsumer, + AtomicReference> futureReference) + { + super(clientApplication); + this.headers = new ClientDataHttpHeaders(clientApplication.getCorrelationId()); + this.clientAuth = clientAuth; + this.scopes = String.join(" ", scopes); + this.deviceCodeConsumer = deviceCodeConsumer; + + this.futureReference = futureReference; + } + + AuthenticationResult execute() throws Exception { + + clientApplication.authenticationAuthority.doInstanceDiscovery(clientApplication.isValidateAuthority(), + headers.getReadonlyHeaderMap(), clientApplication.getProxy(), clientApplication.getSslSocketFactory()); + + DeviceCode deviceCode = DeviceCodeRequest.execute(clientApplication.authenticationAuthority.getDeviceCodeEndpoint(), + clientAuth.getClientID().toString(), scopes, headers.getReadonlyHeaderMap(), clientApplication.getProxy(), + clientApplication.getSslSocketFactory()); + + deviceCodeConsumer.accept(deviceCode); + + MsalDeviceCodeAuthorizationGrant deviceCodeGrant = + new MsalDeviceCodeAuthorizationGrant(deviceCode, deviceCode.getScopes()); + + long expirationTimeInSeconds = + TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()) + deviceCode.getExpiresIn(); + + AcquireTokenSupplier acquireTokenSupplier = + new AcquireTokenSupplier(clientApplication, deviceCodeGrant, clientAuth); + + while (TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()) < expirationTimeInSeconds) { + if(futureReference.get().isCancelled()){ + throw new InterruptedException("Acquire token Device Code Flow was interrupted"); + } + try { + return acquireTokenSupplier.execute(); + } + catch (AuthenticationException ex) { + if (ex.getErrorCode().equals(AUTHORIZATION_PENDING)) + { + TimeUnit.SECONDS.sleep(deviceCode.getInterval()); + } else { + throw ex; + } + } + } + throw new AuthenticationException("Expired Device code"); + } +} diff --git a/src/main/java/com/microsoft/aad/msal4j/AcquireTokenCallable.java b/src/main/java/com/microsoft/aad/msal4j/AcquireTokenSupplier.java similarity index 60% rename from src/main/java/com/microsoft/aad/msal4j/AcquireTokenCallable.java rename to src/main/java/com/microsoft/aad/msal4j/AcquireTokenSupplier.java index e789e2cf..ba572d36 100644 --- a/src/main/java/com/microsoft/aad/msal4j/AcquireTokenCallable.java +++ b/src/main/java/com/microsoft/aad/msal4j/AcquireTokenSupplier.java @@ -1,26 +1,3 @@ -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - package com.microsoft.aad.msal4j; import com.nimbusds.jose.util.Base64URL; @@ -28,18 +5,15 @@ import com.nimbusds.oauth2.sdk.ResourceOwnerPasswordCredentialsGrant; import com.nimbusds.oauth2.sdk.SAML2BearerGrant; import com.nimbusds.oauth2.sdk.auth.ClientAuthentication; -import org.apache.commons.codec.binary.Base64; - -import java.io.UnsupportedEncodingException; +import org.apache.commons.codec.binary.Base64;; import java.net.URLEncoder; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -class AcquireTokenCallable extends MsalCallable { +public class AcquireTokenSupplier extends MsalSupplier { + private AbstractMsalAuthorizationGrant authGrant; private ClientAuthentication clientAuth; - AcquireTokenCallable(ClientApplicationBase clientApplication, + AcquireTokenSupplier(ClientApplicationBase clientApplication, AbstractMsalAuthorizationGrant authGrant, ClientAuthentication clientAuth) { super(clientApplication); this.authGrant = authGrant; @@ -69,51 +43,6 @@ AuthenticationResult execute() throws Exception { return clientApplication.acquireTokenCommon(this.authGrant, this.clientAuth, this.headers); } - @Override - void logResult(AuthenticationResult result, ClientDataHttpHeaders headers) - throws NoSuchAlgorithmException, UnsupportedEncodingException { - - if (!StringHelper.isBlank(result.getAccessToken())) { - - String accessTokenHash = this.computeSha256Hash(result - .getAccessToken()); - if (!StringHelper.isBlank(result.getRefreshToken())) { - String refreshTokenHash = this.computeSha256Hash(result - .getRefreshToken()); - if(clientApplication.isLogPii()){ - clientApplication.log.debug(LogHelper.createMessage(String - .format("Access Token with hash '%s' and Refresh Token with hash '%s' returned", - accessTokenHash, refreshTokenHash), - headers.getHeaderCorrelationIdValue())); - } - else{ - clientApplication.log.debug(LogHelper.createMessage("Access Token and Refresh Token were returned", - headers.getHeaderCorrelationIdValue())); - } - } - else { - if(clientApplication.isLogPii()){ - clientApplication.log.debug(LogHelper.createMessage(String - .format("Access Token with hash '%s' returned", - accessTokenHash), - headers.getHeaderCorrelationIdValue())); - } - else{ - clientApplication.log.debug(LogHelper.createMessage("Access Token was returned", - headers.getHeaderCorrelationIdValue())); - } - } - } - } - - private String computeSha256Hash(String input) - throws NoSuchAlgorithmException, UnsupportedEncodingException { - MessageDigest digest = MessageDigest.getInstance("SHA-256"); - digest.update(input.getBytes("UTF-8")); - byte[] hash = digest.digest(); - return Base64.encodeBase64URLSafeString(hash); - } - /** * @param authGrant */ @@ -165,7 +94,7 @@ AuthorizationGrant getAuthorizationGrantIntegrated(String userName) throws Excep // Get the realm information UserDiscoveryResponse userRealmResponse = UserDiscoveryRequest.execute( - userRealmEndpoint, + userRealmEndpoint, this.headers.getReadonlyHeaderMap(), clientApplication.getProxy(), clientApplication.getSslSocketFactory()); @@ -199,4 +128,5 @@ else if (userRealmResponse.isAccountManaged()) { return updatedGrant; } + } diff --git a/src/main/java/com/microsoft/aad/msal4j/ClientApplicationBase.java b/src/main/java/com/microsoft/aad/msal4j/ClientApplicationBase.java index a9df5eb7..678f267c 100644 --- a/src/main/java/com/microsoft/aad/msal4j/ClientApplicationBase.java +++ b/src/main/java/com/microsoft/aad/msal4j/ClientApplicationBase.java @@ -37,11 +37,7 @@ import java.net.URL; import java.util.Set; import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; -import java.util.function.Supplier; +import java.util.concurrent.*; /** * Abstract class containing common API methods and properties. @@ -121,23 +117,7 @@ protected CompletableFuture acquireToken( final AbstractMsalAuthorizationGrant authGrant, final ClientAuthentication clientAuth) { - Supplier supplier = () -> - { - AcquireTokenCallable callable = - new AcquireTokenCallable(this, authGrant, clientAuth); - - AuthenticationResult result; - try { - result = callable.execute(); - callable.logResult(result, callable.headers); - } catch (Exception ex) { - log.error(LogHelper.createMessage("Execution of " + this.getClass() + " failed.", - callable.headers.getHeaderCorrelationIdValue()), ex); - - throw new CompletionException(ex); - } - return result; - }; + AcquireTokenSupplier supplier = new AcquireTokenSupplier(this, authGrant, clientAuth); CompletableFuture future = executorService != null ? CompletableFuture.supplyAsync(supplier, executorService) @@ -145,6 +125,7 @@ protected CompletableFuture acquireToken( return future; } + protected static void validateNotBlank(String name, String value) { if (StringHelper.isBlank(value)) { throw new IllegalArgumentException(name + " is null or empty"); diff --git a/src/main/java/com/microsoft/aad/msal4j/MsalSupplier.java b/src/main/java/com/microsoft/aad/msal4j/MsalSupplier.java new file mode 100644 index 00000000..b9b732f6 --- /dev/null +++ b/src/main/java/com/microsoft/aad/msal4j/MsalSupplier.java @@ -0,0 +1,89 @@ +package com.microsoft.aad.msal4j; + +import org.apache.commons.codec.binary.Base64; + +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.concurrent.CompletionException; +import java.util.function.Supplier; + +abstract class MsalSupplier implements Supplier { + + ClientDataHttpHeaders headers; + ClientApplicationBase clientApplication; + + MsalSupplier(ClientApplicationBase clientApplication) { + this.clientApplication = clientApplication; + } + + abstract AuthenticationResult execute() throws Exception; + + @Override + public AuthenticationResult get() { + AuthenticationResult result; + try { + result = execute(); + + logResult(result, headers); + } catch (Exception ex) { + clientApplication.log.error( + LogHelper.createMessage("Execution of " + this.getClass() + " failed.", + this.headers.getHeaderCorrelationIdValue()), ex); + + throw new CompletionException(ex); + } + return result; + } + + void logResult(AuthenticationResult result, ClientDataHttpHeaders headers) + { + if (!StringHelper.isBlank(result. getAccessToken())) { + + String accessTokenHash = this.computeSha256Hash(result + .getAccessToken()); + if (!StringHelper.isBlank(result.getRefreshToken())) { + String refreshTokenHash = this.computeSha256Hash(result + .getRefreshToken()); + if(clientApplication.isLogPii()){ + clientApplication.log.debug(LogHelper.createMessage(String + .format("Access Token with hash '%s' and Refresh Token with hash '%s' returned", + accessTokenHash, refreshTokenHash), + headers.getHeaderCorrelationIdValue())); + } + else{ + clientApplication.log.debug( + LogHelper.createMessage("Access Token and Refresh Token were returned", + headers.getHeaderCorrelationIdValue())); + } + } + else { + if(clientApplication.isLogPii()){ + clientApplication.log.debug(LogHelper.createMessage(String + .format("Access Token with hash '%s' returned", + accessTokenHash), + headers.getHeaderCorrelationIdValue())); + } + else{ + clientApplication.log.debug(LogHelper.createMessage("Access Token was returned", + headers.getHeaderCorrelationIdValue())); + } + } + } + } + + private String computeSha256Hash(String input) { + try{ + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + digest.update(input.getBytes("UTF-8")); + byte[] hash = digest.digest(); + return Base64.encodeBase64URLSafeString(hash); + } + catch (NoSuchAlgorithmException | UnsupportedEncodingException ex){ + clientApplication.log.warn( + LogHelper.createMessage("Failed to compute SHA-256 hash due to exception - ", + LogHelper.getPiiScrubbedDetails(ex))); + return "Failed to compute SHA-256 hash"; + } + } +} diff --git a/src/main/java/com/microsoft/aad/msal4j/PublicClientApplication.java b/src/main/java/com/microsoft/aad/msal4j/PublicClientApplication.java index 1cb7132f..43ac0178 100644 --- a/src/main/java/com/microsoft/aad/msal4j/PublicClientApplication.java +++ b/src/main/java/com/microsoft/aad/msal4j/PublicClientApplication.java @@ -30,10 +30,9 @@ import org.slf4j.LoggerFactory; import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionException; -import java.util.concurrent.Future; -import java.util.function.Supplier; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; public class PublicClientApplication extends ClientApplicationBase { @@ -76,7 +75,7 @@ public CompletableFuture acquireTokenByUsernamePassword(Se } /** - * Acquires a security token using integrated authentication flow. + * Acquires a security token using Windows integrated authentication flow. * * @param scopes scopes of the access request * @param username @@ -85,7 +84,7 @@ public CompletableFuture acquireTokenByUsernamePassword(Se * {@link AuthenticationResult} of the call. It contains Access * Token, Refresh Token and the Access Token's expiration time. */ - public CompletableFuture acquireTokenByKerberosAuth(Set scopes, String username) { + public CompletableFuture acquireTokenByWindowsIntegratedAuth(Set scopes, String username) { validateNotEmpty("scopes", scopes); validateNotBlank("username", username); @@ -94,38 +93,42 @@ public CompletableFuture acquireTokenByKerberosAuth(Set acquireDeviceCode(Set scopes) { + public CompletableFuture acquireTokenDeviceCodeFlow(Set scopes, + Consumer deviceCodeConsumer) + { validateDeviceCodeRequestInput(scopes); - Supplier supplier = () -> - { - AcquireDeviceCodeCallable callable = - new AcquireDeviceCodeCallable(this, clientId, scopes); - - DeviceCode result; - try { - result = callable.execute(); - callable.logResult(result, callable.headers); - } catch (Exception ex) { - log.error(LogHelper.createMessage("Execution of " + this.getClass() + " failed.", - callable.headers.getHeaderCorrelationIdValue()), ex); - - throw new CompletionException(ex); - } - return result; - }; - - CompletableFuture future = + AtomicReference> futureReference = new AtomicReference<>(); + + AcquireTokenDeviceCodeFlowSupplier supplier = + new AcquireTokenDeviceCodeFlowSupplier + (this, clientAuthentication, scopes, deviceCodeConsumer, futureReference); + + CompletableFuture future = executorService != null ? CompletableFuture.supplyAsync(supplier, executorService) : CompletableFuture.supplyAsync(supplier); + futureReference.set(future); + return future; } @@ -138,30 +141,6 @@ private void validateDeviceCodeRequestInput(Set scopes) { } } - /** - * Acquires security token from the authority using an device code previously received. - * - * @param deviceCode The device code result received from calling acquireDeviceCode. - * @return A {@link CompletableFuture} object representing the {@link AuthenticationResult} of the call. - * It contains AccessToken, Refresh Token and the Access Token's expiration time. - * @throws AuthenticationException thrown if authorization is pending or another error occurred. - * If the errorCode of the exception is AdalErrorCode.AUTHORIZATION_PENDING, - * the call needs to be retried until the AccessToken is returned. - * DeviceCode.interval - The minimum amount of time in seconds that the client - * SHOULD wait between polling requests to the token endpoint - */ - public CompletableFuture acquireTokenByDeviceCode(DeviceCode deviceCode) - throws AuthenticationException { - - validateNotNull("deviceCode", deviceCode); - validateNotBlank("deviceCode.getScopes()", deviceCode.getScopes()); - - final MsalDeviceCodeAuthorizationGrant deviceCodeGrant = - new MsalDeviceCodeAuthorizationGrant(deviceCode, deviceCode.getScopes()); - - return this.acquireToken(deviceCodeGrant, clientAuthentication); - } - public static class Builder extends ClientApplicationBase.Builder{ /** * Constructor to create instance of Builder of PublicClientApplication diff --git a/src/samples/public-client/DeviceCodeFlow.java b/src/samples/public-client/DeviceCodeFlow.java index b9083fd7..0e81ab55 100644 --- a/src/samples/public-client/DeviceCodeFlow.java +++ b/src/samples/public-client/DeviceCodeFlow.java @@ -25,29 +25,41 @@ import com.microsoft.aad.msal4j.PublicClientApplication; import java.util.Collections; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; +import java.util.function.Consumer; public class DeviceCodeFlow { public static void main(String args[]) throws Exception { - AuthenticationResult result = getAccessTokenByDeviceCodeGrant(); - - System.out.println("Access Token - " + result.getAccessToken()); - System.out.println("Refresh Token - " + result.getRefreshToken()); - System.out.println("ID Token - " + result.getIdToken()); + getAccessTokenByDeviceCodeGrant(); } - private static AuthenticationResult getAccessTokenByDeviceCodeGrant() throws Exception { + private static void getAccessTokenByDeviceCodeGrant() throws Exception { PublicClientApplication app = new PublicClientApplication.Builder(TestData.PUBLIC_CLIENT_ID) .authority(TestData.AUTHORITY) .build(); - Future deviceCodeFuture = app.acquireDeviceCode(Collections.singleton(TestData.GRAPH_DEFAULT_SCOPE)); - DeviceCode deviceCode = deviceCodeFuture.get(); + Consumer deviceCodeConsumer = (DeviceCode deviceCode) -> { + System.out.println(deviceCode.getMessage()); + }; + + CompletableFuture future = + app.acquireTokenDeviceCodeFlow(Collections.singleton(TestData.GRAPH_DEFAULT_SCOPE), deviceCodeConsumer); - Future futureAuthenticationResult = app.acquireTokenByDeviceCode(deviceCode); + future.handle((res, ex) -> { + if(ex != null) { + System.out.println("Oops! We have an exception of type - " + ex.getClass()); + System.out.println("message - " + ex.getMessage()); + return "Unknown!"; + } + System.out.println("Returned ok - " + res); - AuthenticationResult result = futureAuthenticationResult.get(); + System.out.println("Access Token - " + res.getAccessToken()); + System.out.println("Refresh Token - " + res.getRefreshToken()); + System.out.println("ID Token - " + res.getIdToken()); + return res; + }); - return result; + future.join(); } } diff --git a/src/samples/public-client/IntegratedAuthFlow.java b/src/samples/public-client/IntegratedAuthFlow.java index b8cdea45..cd58c835 100644 --- a/src/samples/public-client/IntegratedAuthFlow.java +++ b/src/samples/public-client/IntegratedAuthFlow.java @@ -43,7 +43,7 @@ private static AuthenticationResult getAccessTokenByIntegratedAuth() throws Exce .build(); Future futureAuthenticationResult = - app.acquireTokenByKerberosAuth(Collections.singleton(TestData.GRAPH_DEFAULT_SCOPE), TestData.USER_NAME); + app.acquireTokenByWindowsIntegratedAuth(Collections.singleton(TestData.GRAPH_DEFAULT_SCOPE), TestData.USER_NAME); AuthenticationResult result = futureAuthenticationResult.get(); diff --git a/src/samples/public-client/UsernamePasswordFlowAsync.java b/src/samples/public-client/UsernamePasswordFlow.java similarity index 97% rename from src/samples/public-client/UsernamePasswordFlowAsync.java rename to src/samples/public-client/UsernamePasswordFlow.java index 48054121..97ec6aef 100644 --- a/src/samples/public-client/UsernamePasswordFlowAsync.java +++ b/src/samples/public-client/UsernamePasswordFlow.java @@ -27,7 +27,7 @@ import java.util.Collections; import java.util.concurrent.CompletableFuture; -public class UsernamePasswordFlowAsync { +public class UsernamePasswordFlow { public static void main(String args[]) throws Exception { getAccessTokenFromUserCredentials(); @@ -54,6 +54,6 @@ private static void getAccessTokenFromUserCredentials() throws Exception { return res; }); - Thread.sleep(3000); + future.join(); } } diff --git a/src/test/java/com/microsoft/aad/msal4j/DeviceCodeFlowTest.java b/src/test/java/com/microsoft/aad/msal4j/DeviceCodeFlowTest.java index f2f47e0e..80be290a 100644 --- a/src/test/java/com/microsoft/aad/msal4j/DeviceCodeFlowTest.java +++ b/src/test/java/com/microsoft/aad/msal4j/DeviceCodeFlowTest.java @@ -30,7 +30,8 @@ import java.util.Date; import java.util.HashMap; import java.util.Map; -import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; import com.nimbusds.oauth2.sdk.auth.ClientAuthentication; import com.nimbusds.oauth2.sdk.http.CommonContentTypes; @@ -51,7 +52,6 @@ import static com.microsoft.aad.msal4j.TestConfiguration.AAD_CLIENT_ID; import static com.microsoft.aad.msal4j.TestConfiguration.AAD_HOST_NAME; import static com.microsoft.aad.msal4j.TestConfiguration.AAD_RESOURCE_ID; -import static com.microsoft.aad.msal4j.TestConfiguration.AAD_TENANT_ENDPOINT; import static com.microsoft.aad.msal4j.TestConfiguration.AAD_TENANT_NAME; import static com.microsoft.aad.msal4j.TestConfiguration.ADFS_TENANT_ENDPOINT; @@ -113,8 +113,28 @@ public void deviceCodeFlowTest() throws Exception { PowerMock.replay(HttpHelper.class); - Future result = app.acquireDeviceCode(Collections.singleton(AAD_RESOURCE_ID)); - DeviceCode deviceCode = result.get(); + AtomicReference deviceCodeCorrelationId = new AtomicReference<>(); + + Consumer deviceCodeConsumer = (DeviceCode deviceCode) ->{ + + // validate returned Device Code object + Assert.assertNotNull(deviceCode); + Assert.assertNotNull(deviceCode.getUserCode(), "DW83JNP2P"); + Assert.assertNotNull(deviceCode.getDeviceCode(), "DAQABAAEAAADRNYRQ3dhRFEeqWvq-yi6QodK2pb1iAA"); + Assert.assertNotNull(deviceCode.getVerificationUrl(), "https://aka.ms/devicelogin"); + Assert.assertNotNull(deviceCode.getExpiresIn(), "900"); + Assert.assertNotNull(deviceCode.getInterval(), "5"); + Assert.assertNotNull(deviceCode.getMessage(), "To sign in, use a web browser" + + " to open the page https://aka.ms/devicelogin and enter the code DW83JNP2P to authenticate."); + Assert.assertNotNull(deviceCode.getCorrelationId()); + + deviceCodeCorrelationId.set(deviceCode.getCorrelationId()); + }; + + PowerMock.replay(app); + + AuthenticationResult authResult = + app.acquireTokenDeviceCodeFlow(Collections.singleton(AAD_RESOURCE_ID), deviceCodeConsumer).get(); // validate HTTP GET request used to get device code URL url = new URL(capturedUrl.getValue()); @@ -129,25 +149,9 @@ public void deviceCodeFlowTest() throws Exception { Assert.assertEquals(getQueryMap(url.getQuery()), expectedQueryParams); - // validate returned Device Code object - Assert.assertNotNull(deviceCode); - Assert.assertNotNull(deviceCode.getUserCode(), "DW83JNP2P"); - Assert.assertNotNull(deviceCode.getDeviceCode(), "DAQABAAEAAADRNYRQ3dhRFEeqWvq-yi6QodK2pb1iAA"); - Assert.assertNotNull(deviceCode.getVerificationUrl(), "https://aka.ms/devicelogin"); - Assert.assertNotNull(deviceCode.getExpiresIn(), "900"); - Assert.assertNotNull(deviceCode.getInterval(), "5"); - Assert.assertNotNull(deviceCode.getMessage(), "To sign in, use a web browser" + - " to open the page https://aka.ms/devicelogin and enter the code DW83JNP2P to authenticate."); - Assert.assertNotNull(deviceCode.getCorrelationId()); - - PowerMock.replay(app); - - Future authResult = app.acquireTokenByDeviceCode(deviceCode); - authResult.get(); - // make sure same correlation id is used for acquireDeviceCode and acquireTokenByDeviceCode calls Assert.assertEquals(capturedClientDataHttpHeaders.getValue().getReadonlyHeaderMap(). - get(ClientDataHttpHeaders.CORRELATION_ID_HEADER_NAME), deviceCode.getCorrelationId()); + get(ClientDataHttpHeaders.CORRELATION_ID_HEADER_NAME), deviceCodeCorrelationId.get()); Assert.assertNotNull(authResult); PowerMock.verify(); @@ -162,7 +166,7 @@ public void executeAcquireDeviceCode_AdfsAuthorityUsed_IllegalArgumentExceptionT .authority(ADFS_TENANT_ENDPOINT) .validateAuthority(false).build(); - app.acquireDeviceCode(Collections.singleton(AAD_RESOURCE_ID)); + app.acquireTokenDeviceCodeFlow(Collections.singleton(AAD_RESOURCE_ID), (DeviceCode deviceCode) -> {}); } @Test From d8a9f35d952723d5cc5eb5382a337890e974af1a Mon Sep 17 00:00:00 2001 From: Petro Somka Date: Wed, 20 Feb 2019 15:23:53 -0800 Subject: [PATCH 2/4] addressing pr comments --- .../AcquireTokenDeviceCodeFlowSupplier.java | 25 ++++++++++++++++- .../aad/msal4j/AcquireTokenSupplier.java | 26 ++++++++++++++++-- ...java => AuthenticationResultSupplier.java} | 27 +++++++++++++++++-- .../aad/msal4j/ClientApplicationBase.java | 1 - 4 files changed, 73 insertions(+), 6 deletions(-) rename src/main/java/com/microsoft/aad/msal4j/{MsalSupplier.java => AuthenticationResultSupplier.java} (71%) diff --git a/src/main/java/com/microsoft/aad/msal4j/AcquireTokenDeviceCodeFlowSupplier.java b/src/main/java/com/microsoft/aad/msal4j/AcquireTokenDeviceCodeFlowSupplier.java index 692d8454..ca7ee670 100644 --- a/src/main/java/com/microsoft/aad/msal4j/AcquireTokenDeviceCodeFlowSupplier.java +++ b/src/main/java/com/microsoft/aad/msal4j/AcquireTokenDeviceCodeFlowSupplier.java @@ -1,3 +1,26 @@ +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + package com.microsoft.aad.msal4j; import com.nimbusds.oauth2.sdk.auth.ClientAuthentication; @@ -10,7 +33,7 @@ import static com.microsoft.aad.msal4j.AdalErrorCode.AUTHORIZATION_PENDING; -public class AcquireTokenDeviceCodeFlowSupplier extends MsalSupplier { +public class AcquireTokenDeviceCodeFlowSupplier extends AuthenticationResultSupplier { private ClientAuthentication clientAuth; private String scopes; diff --git a/src/main/java/com/microsoft/aad/msal4j/AcquireTokenSupplier.java b/src/main/java/com/microsoft/aad/msal4j/AcquireTokenSupplier.java index ba572d36..aa8efebc 100644 --- a/src/main/java/com/microsoft/aad/msal4j/AcquireTokenSupplier.java +++ b/src/main/java/com/microsoft/aad/msal4j/AcquireTokenSupplier.java @@ -1,3 +1,26 @@ +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + package com.microsoft.aad.msal4j; import com.nimbusds.jose.util.Base64URL; @@ -8,7 +31,7 @@ import org.apache.commons.codec.binary.Base64;; import java.net.URLEncoder; -public class AcquireTokenSupplier extends MsalSupplier { +public class AcquireTokenSupplier extends AuthenticationResultSupplier { private AbstractMsalAuthorizationGrant authGrant; private ClientAuthentication clientAuth; @@ -128,5 +151,4 @@ else if (userRealmResponse.isAccountManaged()) { return updatedGrant; } - } diff --git a/src/main/java/com/microsoft/aad/msal4j/MsalSupplier.java b/src/main/java/com/microsoft/aad/msal4j/AuthenticationResultSupplier.java similarity index 71% rename from src/main/java/com/microsoft/aad/msal4j/MsalSupplier.java rename to src/main/java/com/microsoft/aad/msal4j/AuthenticationResultSupplier.java index b9b732f6..a8a446ac 100644 --- a/src/main/java/com/microsoft/aad/msal4j/MsalSupplier.java +++ b/src/main/java/com/microsoft/aad/msal4j/AuthenticationResultSupplier.java @@ -1,3 +1,26 @@ +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + package com.microsoft.aad.msal4j; import org.apache.commons.codec.binary.Base64; @@ -8,12 +31,12 @@ import java.util.concurrent.CompletionException; import java.util.function.Supplier; -abstract class MsalSupplier implements Supplier { +abstract class AuthenticationResultSupplier implements Supplier { ClientDataHttpHeaders headers; ClientApplicationBase clientApplication; - MsalSupplier(ClientApplicationBase clientApplication) { + AuthenticationResultSupplier(ClientApplicationBase clientApplication) { this.clientApplication = clientApplication; } diff --git a/src/main/java/com/microsoft/aad/msal4j/ClientApplicationBase.java b/src/main/java/com/microsoft/aad/msal4j/ClientApplicationBase.java index 678f267c..af926b76 100644 --- a/src/main/java/com/microsoft/aad/msal4j/ClientApplicationBase.java +++ b/src/main/java/com/microsoft/aad/msal4j/ClientApplicationBase.java @@ -125,7 +125,6 @@ protected CompletableFuture acquireToken( return future; } - protected static void validateNotBlank(String name, String value) { if (StringHelper.isBlank(value)) { throw new IllegalArgumentException(name + " is null or empty"); From 9d18101a38173cad6b978013dcc69bcbf0ce82c1 Mon Sep 17 00:00:00 2001 From: Petro Somka Date: Thu, 21 Feb 2019 18:23:02 -0800 Subject: [PATCH 3/4] addressing pr comments --- ...r.java => AcquireTokenByAuthorisationGrantSupplier.java} | 6 +++--- .../aad/msal4j/AcquireTokenDeviceCodeFlowSupplier.java | 6 +++--- .../com/microsoft/aad/msal4j/ClientApplicationBase.java | 2 +- .../com/microsoft/aad/msal4j/PublicClientApplication.java | 2 +- ...tegratedAuthFlow.java => IntegratedWindowsAuthFlow.java} | 4 ++-- .../java/com/microsoft/aad/msal4j/DeviceCodeFlowTest.java | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) rename src/main/java/com/microsoft/aad/msal4j/{AcquireTokenSupplier.java => AcquireTokenByAuthorisationGrantSupplier.java} (95%) rename src/samples/public-client/{IntegratedAuthFlow.java => IntegratedWindowsAuthFlow.java} (95%) diff --git a/src/main/java/com/microsoft/aad/msal4j/AcquireTokenSupplier.java b/src/main/java/com/microsoft/aad/msal4j/AcquireTokenByAuthorisationGrantSupplier.java similarity index 95% rename from src/main/java/com/microsoft/aad/msal4j/AcquireTokenSupplier.java rename to src/main/java/com/microsoft/aad/msal4j/AcquireTokenByAuthorisationGrantSupplier.java index aa8efebc..e0fde352 100644 --- a/src/main/java/com/microsoft/aad/msal4j/AcquireTokenSupplier.java +++ b/src/main/java/com/microsoft/aad/msal4j/AcquireTokenByAuthorisationGrantSupplier.java @@ -31,13 +31,13 @@ import org.apache.commons.codec.binary.Base64;; import java.net.URLEncoder; -public class AcquireTokenSupplier extends AuthenticationResultSupplier { +public class AcquireTokenByAuthorisationGrantSupplier extends AuthenticationResultSupplier { private AbstractMsalAuthorizationGrant authGrant; private ClientAuthentication clientAuth; - AcquireTokenSupplier(ClientApplicationBase clientApplication, - AbstractMsalAuthorizationGrant authGrant, ClientAuthentication clientAuth) { + AcquireTokenByAuthorisationGrantSupplier(ClientApplicationBase clientApplication, + AbstractMsalAuthorizationGrant authGrant, ClientAuthentication clientAuth) { super(clientApplication); this.authGrant = authGrant; this.clientAuth = clientAuth; diff --git a/src/main/java/com/microsoft/aad/msal4j/AcquireTokenDeviceCodeFlowSupplier.java b/src/main/java/com/microsoft/aad/msal4j/AcquireTokenDeviceCodeFlowSupplier.java index ca7ee670..bffe727c 100644 --- a/src/main/java/com/microsoft/aad/msal4j/AcquireTokenDeviceCodeFlowSupplier.java +++ b/src/main/java/com/microsoft/aad/msal4j/AcquireTokenDeviceCodeFlowSupplier.java @@ -70,15 +70,15 @@ AuthenticationResult execute() throws Exception { long expirationTimeInSeconds = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()) + deviceCode.getExpiresIn(); - AcquireTokenSupplier acquireTokenSupplier = - new AcquireTokenSupplier(clientApplication, deviceCodeGrant, clientAuth); + AcquireTokenByAuthorisationGrantSupplier acquireTokenByAuthorisationGrantSupplier = + new AcquireTokenByAuthorisationGrantSupplier(clientApplication, deviceCodeGrant, clientAuth); while (TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()) < expirationTimeInSeconds) { if(futureReference.get().isCancelled()){ throw new InterruptedException("Acquire token Device Code Flow was interrupted"); } try { - return acquireTokenSupplier.execute(); + return acquireTokenByAuthorisationGrantSupplier.execute(); } catch (AuthenticationException ex) { if (ex.getErrorCode().equals(AUTHORIZATION_PENDING)) diff --git a/src/main/java/com/microsoft/aad/msal4j/ClientApplicationBase.java b/src/main/java/com/microsoft/aad/msal4j/ClientApplicationBase.java index af926b76..cbf9ade8 100644 --- a/src/main/java/com/microsoft/aad/msal4j/ClientApplicationBase.java +++ b/src/main/java/com/microsoft/aad/msal4j/ClientApplicationBase.java @@ -117,7 +117,7 @@ protected CompletableFuture acquireToken( final AbstractMsalAuthorizationGrant authGrant, final ClientAuthentication clientAuth) { - AcquireTokenSupplier supplier = new AcquireTokenSupplier(this, authGrant, clientAuth); + AcquireTokenByAuthorisationGrantSupplier supplier = new AcquireTokenByAuthorisationGrantSupplier(this, authGrant, clientAuth); CompletableFuture future = executorService != null ? CompletableFuture.supplyAsync(supplier, executorService) diff --git a/src/main/java/com/microsoft/aad/msal4j/PublicClientApplication.java b/src/main/java/com/microsoft/aad/msal4j/PublicClientApplication.java index 43ac0178..6972ef20 100644 --- a/src/main/java/com/microsoft/aad/msal4j/PublicClientApplication.java +++ b/src/main/java/com/microsoft/aad/msal4j/PublicClientApplication.java @@ -84,7 +84,7 @@ public CompletableFuture acquireTokenByUsernamePassword(Se * {@link AuthenticationResult} of the call. It contains Access * Token, Refresh Token and the Access Token's expiration time. */ - public CompletableFuture acquireTokenByWindowsIntegratedAuth(Set scopes, String username) { + public CompletableFuture acquireTokenByIntegratedWindowsAuth(Set scopes, String username) { validateNotEmpty("scopes", scopes); validateNotBlank("username", username); diff --git a/src/samples/public-client/IntegratedAuthFlow.java b/src/samples/public-client/IntegratedWindowsAuthFlow.java similarity index 95% rename from src/samples/public-client/IntegratedAuthFlow.java rename to src/samples/public-client/IntegratedWindowsAuthFlow.java index cd58c835..5a43eb6c 100644 --- a/src/samples/public-client/IntegratedAuthFlow.java +++ b/src/samples/public-client/IntegratedWindowsAuthFlow.java @@ -27,7 +27,7 @@ import java.util.Collections; import java.util.concurrent.Future; -public class IntegratedAuthFlow { +public class IntegratedWindowsAuthFlow { public static void main(String args[]) throws Exception { AuthenticationResult result = getAccessTokenByIntegratedAuth(); @@ -43,7 +43,7 @@ private static AuthenticationResult getAccessTokenByIntegratedAuth() throws Exce .build(); Future futureAuthenticationResult = - app.acquireTokenByWindowsIntegratedAuth(Collections.singleton(TestData.GRAPH_DEFAULT_SCOPE), TestData.USER_NAME); + app.acquireTokenByIntegratedWindowsAuth(Collections.singleton(TestData.GRAPH_DEFAULT_SCOPE), TestData.USER_NAME); AuthenticationResult result = futureAuthenticationResult.get(); diff --git a/src/test/java/com/microsoft/aad/msal4j/DeviceCodeFlowTest.java b/src/test/java/com/microsoft/aad/msal4j/DeviceCodeFlowTest.java index 80be290a..ae056265 100644 --- a/src/test/java/com/microsoft/aad/msal4j/DeviceCodeFlowTest.java +++ b/src/test/java/com/microsoft/aad/msal4j/DeviceCodeFlowTest.java @@ -124,7 +124,7 @@ public void deviceCodeFlowTest() throws Exception { Assert.assertNotNull(deviceCode.getVerificationUrl(), "https://aka.ms/devicelogin"); Assert.assertNotNull(deviceCode.getExpiresIn(), "900"); Assert.assertNotNull(deviceCode.getInterval(), "5"); - Assert.assertNotNull(deviceCode.getMessage(), "To sign in, use a web browser" + + Assert.assertEquals(deviceCode.getMessage(), "To sign in, use a web browser" + " to open the page https://aka.ms/devicelogin and enter the code DW83JNP2P to authenticate."); Assert.assertNotNull(deviceCode.getCorrelationId()); From 6354ccf6b46974e7cc0ff750482c6c869db2fbdf Mon Sep 17 00:00:00 2001 From: Petro Somka Date: Mon, 25 Feb 2019 18:05:41 -0800 Subject: [PATCH 4/4] pr comments --- .../com/microsoft/aad/msal4j/PublicClientApplication.java | 4 ++-- src/samples/public-client/DeviceCodeFlow.java | 3 +-- .../java/com/microsoft/aad/msal4j/DeviceCodeFlowTest.java | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/microsoft/aad/msal4j/PublicClientApplication.java b/src/main/java/com/microsoft/aad/msal4j/PublicClientApplication.java index 6972ef20..eee6a85e 100644 --- a/src/main/java/com/microsoft/aad/msal4j/PublicClientApplication.java +++ b/src/main/java/com/microsoft/aad/msal4j/PublicClientApplication.java @@ -113,8 +113,8 @@ public CompletableFuture acquireTokenByIntegratedWindowsAu * DeviceCode.interval - The minimum amount of time in seconds that the client * SHOULD wait between polling requests to the token endpoint */ - public CompletableFuture acquireTokenDeviceCodeFlow(Set scopes, - Consumer deviceCodeConsumer) + public CompletableFuture acquireTokenByDeviceCodeFlow(Set scopes, + Consumer deviceCodeConsumer) { validateDeviceCodeRequestInput(scopes); diff --git a/src/samples/public-client/DeviceCodeFlow.java b/src/samples/public-client/DeviceCodeFlow.java index 0e81ab55..54cb873d 100644 --- a/src/samples/public-client/DeviceCodeFlow.java +++ b/src/samples/public-client/DeviceCodeFlow.java @@ -26,7 +26,6 @@ import java.util.Collections; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Future; import java.util.function.Consumer; public class DeviceCodeFlow { @@ -44,7 +43,7 @@ private static void getAccessTokenByDeviceCodeGrant() throws Exception { }; CompletableFuture future = - app.acquireTokenDeviceCodeFlow(Collections.singleton(TestData.GRAPH_DEFAULT_SCOPE), deviceCodeConsumer); + app.acquireTokenByDeviceCodeFlow(Collections.singleton(TestData.GRAPH_DEFAULT_SCOPE), deviceCodeConsumer); future.handle((res, ex) -> { if(ex != null) { diff --git a/src/test/java/com/microsoft/aad/msal4j/DeviceCodeFlowTest.java b/src/test/java/com/microsoft/aad/msal4j/DeviceCodeFlowTest.java index ae056265..ce46089c 100644 --- a/src/test/java/com/microsoft/aad/msal4j/DeviceCodeFlowTest.java +++ b/src/test/java/com/microsoft/aad/msal4j/DeviceCodeFlowTest.java @@ -134,7 +134,7 @@ public void deviceCodeFlowTest() throws Exception { PowerMock.replay(app); AuthenticationResult authResult = - app.acquireTokenDeviceCodeFlow(Collections.singleton(AAD_RESOURCE_ID), deviceCodeConsumer).get(); + app.acquireTokenByDeviceCodeFlow(Collections.singleton(AAD_RESOURCE_ID), deviceCodeConsumer).get(); // validate HTTP GET request used to get device code URL url = new URL(capturedUrl.getValue()); @@ -166,7 +166,7 @@ public void executeAcquireDeviceCode_AdfsAuthorityUsed_IllegalArgumentExceptionT .authority(ADFS_TENANT_ENDPOINT) .validateAuthority(false).build(); - app.acquireTokenDeviceCodeFlow(Collections.singleton(AAD_RESOURCE_ID), (DeviceCode deviceCode) -> {}); + app.acquireTokenByDeviceCodeFlow(Collections.singleton(AAD_RESOURCE_ID), (DeviceCode deviceCode) -> {}); } @Test