[Ignore] // Failing sporadically https://identitydivision.visualstudio.com/Engineering/_workitems/edit/1045664 public async Task SilentAuth_MsaUser_ForceRefresh_Async() { var labResponse = await LabUserHelper.GetMsaUserAsync().ConfigureAwait(false); pca = PublicClientApplicationBuilder .Create(LabApiConstants.MSAOutlookAccountClientID) .WithTestLogging() .WithAuthority(AadAuthorityAudience.PersonalMicrosoftAccount) .Build(); Trace.WriteLine("Part 1 - Acquire a token with device code with msa user"); AuthenticationResult authResult = await pca.AcquireTokenWithDeviceCode(s_scopes, deviceCodeResult => { SeleniumExtensions.PerformDeviceCodeLogin( deviceCodeResult, labResponse.User, TestContext, false); return(Task.FromResult(0)); }).ExecuteAsync() .ConfigureAwait(false); await ValidateAuthResultAsync(authResult, labResponse).ConfigureAwait(false); }
public async Task AuthenticateRequestAsync(HttpRequestMessage request) { if (string.IsNullOrEmpty(_authToken)) { var result = await _application.AcquireTokenWithDeviceCode(_scopes, callback => { string[] parts = callback.Message.Split(' '); var code = parts[Array.FindIndex(parts, a => a.Trim() == "code") + 1]; TextCopy.Clipboard.SetText(code); OpenBrowser("https://www.microsoft.com/devicelogin"); Console.WriteLine(callback.Message); return(Task.FromResult(0)); }).ExecuteAsync(); _authResult = result; _authToken = result.AccessToken; var accounts = await _application.GetAccountsAsync(); _account = accounts.FirstOrDefault(); } if (_authResult.ExpiresOn.ToLocalTime() <= DateTime.Now) { var result = await _application.AcquireTokenSilent(_scopes, _account).ExecuteAsync(); _authResult = result; _authToken = result.AccessToken; var accounts = await _application.GetAccountsAsync(); _account = accounts.FirstOrDefault(); } request.Headers.Authorization = new AuthenticationHeaderValue("bearer", _authToken); }
/// <summary> /// Force to signin the user in an interactive authentication flow. /// </summary> /// <returns></returns> public async Task ForceInteractiveSignIn() { try { OnAuthenticationChanged?.Invoke(this, AuthenticationState.StartedInteractive); var authResult = await identityClientApp.AcquireTokenInteractive(grantScopes).ExecuteAsync(); // Set access token and expiration TokenForUser = authResult.AccessToken; Expiration = authResult.ExpiresOn; OnAuthenticationChanged?.Invoke(this, AuthenticationState.Completed); } catch (Exception e) when(e is PlatformNotSupportedException || e is MsalUiRequiredException) { var authResult = await identityClientApp.AcquireTokenWithDeviceCode(grantScopes, dcr => { OnAuthenticationChanged?.Invoke(this, AuthenticationState.FallbackToDeviceCode); OnPresentDeviceCode?.Invoke(this, dcr); return(Task.FromResult(0)); }).ExecuteAsync(); // Set access token and expiration TokenForUser = authResult.AccessToken; Expiration = authResult.ExpiresOn; OnAuthenticationChanged?.Invoke(this, AuthenticationState.Completed); } catch (Exception) { OnAuthenticationChanged?.Invoke(this, AuthenticationState.Failed); } }
public async Task <string> GetAccessToken() { if (_userAccount == null) { try { var result = await _msalClient.AcquireTokenWithDeviceCode(_scopes, callback => { Console.WriteLine(callback.Message); return(Task.FromResult(0)); }).ExecuteAsync(); _userAccount = result.Account; return(result.AccessToken); } catch (Exception exception) { Console.WriteLine($"Error getting access token:{exception.Message}"); return(null); } } else { var result = await _msalClient .AcquireTokenSilent(_scopes, _userAccount) .ExecuteAsync(); return(result.AccessToken); } }
public async Task AuthenticateAsync( CancellationToken cancellationToken = default ) { // We will use device code flow authentication for Unix systems. // https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Device-Code-Flow // ToDo: Add timeout. var microsoftGraphAuthenticationResult = await _publicClientApplication .AcquireTokenWithDeviceCode( MicrosoftGraphIAIScopes, deviceCodeResult => { // This will print the message on the console which tells the user where to go sign-in using // a separate browser and the code to enter once they sign in. // The AcquireTokenWithDeviceCode() method will poll the server after firing this // device code callback to look for the successful login of the user via that browser. // This background polling (whose interval and timeout data is also provided as fields in the // deviceCodeCallback class) will occur until: // * The user has successfully logged in via browser and entered the proper code // * The timeout specified by the server for the lifetime of this code (typically ~15 minutes) has been reached // * The developing application calls the Cancel() method on a CancellationToken sent into the method. // If this occurs, an OperationCanceledException will be thrown (see catch below for more details). Console.WriteLine(deviceCodeResult.Message); return(Task.FromResult(0)); }) .ExecuteAsync(); // Extract account from microsoftGraphAuthenticationResult _account = microsoftGraphAuthenticationResult.Account; // Validate that we have received Tokens. await AcquireMicrosoftGraphAuthenticationResultAsync(cancellationToken); await AcquireAzureManagementAuthenticationResultAsync(cancellationToken); await AcquireKeyVaultAuthenticationResultAsync(cancellationToken); }
public async Task <string> GetAccessToken() { // If there is no saved user account, the user must sign-in if (_userAccount == null) { try { // Invoke device code flow so user can sign-in with a browser var result = await _msalClient.AcquireTokenWithDeviceCode(_scopes, callback => { Console.WriteLine(callback.Message); return(Task.FromResult(0)); }).ExecuteAsync(); _userAccount = result.Account; return(result.AccessToken); } catch (Exception exception) { Console.WriteLine($"Error getting access token: {exception.Message}"); return(null); } } else { // If there is an account, call AcquireTokenSilent // By doing this, MSAL will refresh the token automatically if // it is expired. Otherwise it returns the cached token. var result = await _msalClient .AcquireTokenSilent(_scopes, _userAccount) .ExecuteAsync(); return(result.AccessToken); } }
private async Task <AuthenticationResult> AcquireByDeviceCodeAsync(IPublicClientApplication pca) { try { var result = await pca.AcquireTokenWithDeviceCode(_scopes, deviceCodeResult => { // This will print the message on the console which tells the user where to go sign-in using // a separate browser and the code to enter once they sign in. // The AcquireTokenWithDeviceCode() method will poll the server after firing this // device code callback to look for the successful login of the user via that browser. // This background polling (whose interval and timeout data is also provided as fields in the // deviceCodeCallback class) will occur until: // * The user has successfully logged in via browser and entered the proper code // * The timeout specified by the server for the lifetime of this code (typically ~15 minutes) has been reached // * The developing application calls the Cancel() method on a CancellationToken sent into the method. // If this occurs, an OperationCanceledException will be thrown (see catch below for more details). Console.WriteLine(deviceCodeResult.Message); return(Task.FromResult(0)); }).ExecuteAsync(); Console.WriteLine(result.Account.Username); return(result); } // TODO: handle or throw all these exceptions catch (MsalServiceException ex) { // Kind of errors you could have (in ex.Message) // AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. // Mitigation: as explained in the message from Azure AD, the authoriy needs to be tenanted. you have probably created // your public client application with the following authorities: // https://login.microsoftonline.com/common or https://login.microsoftonline.com/organizations // AADSTS90133: Device Code flow is not supported under /common or /consumers endpoint. // Mitigation: as explained in the message from Azure AD, the authority needs to be tenanted // AADSTS90002: Tenant <tenantId or domain you used in the authority> not found. This may happen if there are // no active subscriptions for the tenant. Check with your subscription administrator. // Mitigation: if you have an active subscription for the tenant this might be that you have a typo in the // tenantId (GUID) or tenant domain name. throw ex; } catch (OperationCanceledException ex) { // If you use a CancellationToken, and call the Cancel() method on it, then this *may* be triggered // to indicate that the operation was cancelled. // See https://docs.microsoft.com/en-us/dotnet/standard/threading/cancellation-in-managed-threads // for more detailed information on how C# supports cancellation in managed threads. throw ex; } catch (MsalClientException ex) { // Possible cause - verification code expired before contacting the server // This exception will occur if the user does not manage to sign-in before a time out (15 mins) and the // call to `AcquireTokenWithDeviceCode` is not cancelled in between throw ex; } }
private async Task <AccessToken> GetTokenViaDeviceCodeAsync(string[] scopes, CancellationToken cancellationToken) { AuthenticationResult result = await _pubApp.AcquireTokenWithDeviceCode(scopes, code => DeviceCodeCallback(code, cancellationToken)).ExecuteAsync(cancellationToken).ConfigureAwait(false); _account = result.Account; return(new AccessToken(result.AccessToken, result.ExpiresOn)); }
private async Task <AuthenticationResult> GetResponseAsync(IPublicClientApplication app, IEnumerable <string> scopes, CancellationToken cancellationToken) { return(await app.AcquireTokenWithDeviceCode(scopes, deviceCodeResult => { WriteWarning(deviceCodeResult.Message); return Task.CompletedTask; }).ExecuteAsync(cancellationToken)); }
private async Task <string> getAccessToken() { var result = await msalClient.AcquireTokenWithDeviceCode(_scopes, callback => { Console.WriteLine(callback.Message); return(Task.FromResult(0)); }).ExecuteAsync(); return(result.AccessToken); }
/// <summary> /// Gets an access token for the requested resource and scope /// </summary> /// <param name="resource">Resource to request an access token for (unused)</param> /// <param name="scopes">Scopes to request</param> /// <returns>An access token</returns> public override async Task <string> GetAccessTokenAsync(Uri resource, string[] scopes) { if (resource == null) { throw new ArgumentNullException(nameof(resource)); } if (scopes == null) { throw new ArgumentNullException(nameof(scopes)); } if (DeviceCodeVerification == null) { throw new ConfigurationErrorsException( PnPCoreAuthResources.DeviceCodeAuthenticationProvider_MissingDeviceCodeVerification); } AuthenticationResult tokenResult = null; var account = await publicClientApplication.GetAccountsAsync().ConfigureAwait(false); try { // Try to get the token from the tokens cache tokenResult = await publicClientApplication.AcquireTokenSilent(scopes, account.FirstOrDefault()) .ExecuteAsync().ConfigureAwait(false); } catch (MsalUiRequiredException) { // Try to get the token directly through AAD if it is not available in the tokens cache tokenResult = await publicClientApplication.AcquireTokenWithDeviceCode(scopes, deviceCodeResult => { DeviceCodeVerification.Invoke(new DeviceCodeNotification { UserCode = deviceCodeResult.UserCode, Message = deviceCodeResult.Message, VerificationUrl = new Uri(deviceCodeResult.VerificationUrl) }); return(Task.FromResult(0)); }) .ExecuteAsync().ConfigureAwait(false); } // Log the access token retrieval action Log?.LogInformation(PnPCoreAuthResources.AuthenticationProvider_LogAccessTokenRetrieval, GetType().Name, resource, scopes.Aggregate(string.Empty, (c, n) => c + ", " + n).TrimEnd(',')); // Return the Access Token, if we've got it // In case of any exception while retrieving the access token, // MSAL will throw an exception that we simply bubble up return(tokenResult.AccessToken); }
/// <summary> /// Apply this authenticator to the given authentication parameters. /// </summary> /// <param name="parameters">The complex object containing authentication specific information.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param> /// <returns> /// An instance of <see cref="AuthenticationToken" /> that represents the access token generated as result of a successful authenication. /// </returns> public override async Task <AuthenticationResult> AuthenticateAsync(AuthenticationParameters parameters, CancellationToken cancellationToken = default) { IPublicClientApplication app = GetClient(parameters.Account, parameters.Environment).AsPublicClient(); ServiceClientTracing.Information($"[DeviceCodeAuthenticator] Calling AcquireTokenWithDeviceCode - Scopes: '{string.Join(", ", parameters.Scopes)}'"); return(await app.AcquireTokenWithDeviceCode(parameters.Scopes, deviceCodeResult => { WriteWarning(deviceCodeResult.Message); return Task.CompletedTask; }).ExecuteAsync(cancellationToken).ConfigureAwait(false)); }
/// <inheritdoc/> protected override async Task <TokenResultModel> GetTokenAsync( IPublicClientApplication client, string resource, IEnumerable <string> scopes) { // Go and get it through device code. var result = await client.AcquireTokenWithDeviceCode( scopes, deviceCodeCallback => { _prompt.Prompt(deviceCodeCallback.DeviceCode, deviceCodeCallback.ExpiresOn, deviceCodeCallback.Message); return(Task.CompletedTask); }).ExecuteAsync(); return(result.ToTokenResult()); }
public async Task AuthenticateRequestAsync(HttpRequestMessage request) { if (string.IsNullOrEmpty(_authToken)) { var result = await _application.AcquireTokenWithDeviceCode(_scopes, callback => { Console.WriteLine(callback.Message); return(Task.FromResult(0)); }).ExecuteAsync(); _authToken = result.AccessToken; } request.Headers.Authorization = new AuthenticationHeaderValue("bearer", _authToken); }
public async Task VerifyCode(Func <string, Task> deviceCodeCallback) { try { _authResult = await _pca.AcquireTokenWithDeviceCode(new[] { "User.Read.All" }, result => { return(deviceCodeCallback(result.Message)); }).ExecuteAsync(); } catch (MsalClientException ex) { throw new VerificationException(ex.Message, ex, ex.ErrorCode); } }
private async Task RenewToken() { Console.WriteLine("Getting new OAuth token"); // On Azure Function consumption plan the tokencache is storage on the azure function blob storage var scopesDefault = new string[] { $"{resourceUrl}/.default" }; AuthenticationResult result = null; var accounts = await clientApplication.GetAccountsAsync(); if (accounts.Count() != 0) { // All AcquireToken* methods store the tokens in the cache, so check the cache first try { result = await clientApplication.AcquireTokenSilent(scopesDefault, accounts.FirstOrDefault()).ExecuteAsync(); } // A MsalUiRequiredException happened on AcquireTokenSilent. This indicates you need to call AcquireTokenInteractive to acquire a token catch (MsalUiRequiredException) { } } if (result == null || string.IsNullOrEmpty(result.AccessToken)) { if (this.interactiveLogin) { result = await clientApplication .AcquireTokenInteractive(scopesDefault) .ExecuteAsync(); } else { result = await clientApplication.AcquireTokenWithDeviceCode(scopesDefault, deviceCodeCallback => { var msg = $"Go to {deviceCodeCallback.VerificationUrl} and enter device code {deviceCodeCallback.UserCode}"; Console.WriteLine(msg); return(Task.FromResult(0)); }).ExecuteAsync(); } } token = result; }
public static GraphToken AcquireApplicationTokenDeviceLogin(string clientId, string[] scopes, Action <DeviceCodeResult> callBackAction) { var officeManagementApiScopes = Enum.GetNames(typeof(OfficeManagementApiPermission)).Select(s => s.Replace("_", ".")).Intersect(scopes).ToArray(); // Take the remaining scopes and try requesting them from the Microsoft Graph API scopes = scopes.Except(officeManagementApiScopes).ToArray(); if (string.IsNullOrEmpty(clientId)) { throw new ArgumentNullException(nameof(clientId)); } if (scopes == null || scopes.Length == 0) { throw new ArgumentNullException(nameof(scopes)); } if (publicClientApplication == null) { publicClientApplication = PublicClientApplicationBuilder.Create(clientId).Build(); } AuthenticationResult tokenResult = null; if (publicClientApplication == null) { publicClientApplication = PublicClientApplicationBuilder.Create(clientId).WithAuthority($"{OAuthBaseUrl}organizations/").Build(); } var account = publicClientApplication.GetAccountsAsync().GetAwaiter().GetResult(); try { tokenResult = publicClientApplication.AcquireTokenSilent(scopes, account.First()).ExecuteAsync().GetAwaiter().GetResult(); } catch { var builder = publicClientApplication.AcquireTokenWithDeviceCode(scopes, result => { if (callBackAction != null) { callBackAction(result); } return(Task.FromResult(0)); }); tokenResult = builder.ExecuteAsync().GetAwaiter().GetResult(); } return(new GraphToken(tokenResult.AccessToken)); }
public bool CreatePublicClient(bool prompt, bool deviceLogin = false) { Log.Info($"enter: {prompt} {deviceLogin}"); _publicClientApp = PublicClientApplicationBuilder .Create(_wellKnownClientId) .WithAuthority(AzureCloudInstance.AzurePublic, Config.AzureTenantId) .WithLogging(MsalLoggerCallback, LogLevel.Verbose, true, true) .WithDefaultRedirectUri() .Build(); if (_instance.IsWindows) { TokenCacheHelper.EnableSerialization(_publicClientApp.UserTokenCache); } if (prompt) { if (deviceLogin) { AuthenticationResult = _publicClientApp .AcquireTokenWithDeviceCode(_defaultScope, MsalDeviceCodeCallback) .ExecuteAsync().Result; } else { AuthenticationResult = _publicClientApp .AcquireTokenInteractive(_defaultScope) .ExecuteAsync().Result; } } else { AuthenticationResult = _publicClientApp .AcquireTokenSilent(_defaultScope, _publicClientApp.GetAccountsAsync().Result.FirstOrDefault()) .ExecuteAsync().Result; } if (Scopes.Count > 0) { Log.Info($"adding scopes {Scopes.Count}"); AuthenticationResult = _publicClientApp .AcquireTokenSilent(Scopes, _publicClientApp.GetAccountsAsync().Result.FirstOrDefault()) .ExecuteAsync().Result; } return(true); }
public bool CreatePublicClient(bool prompt, bool deviceLogin = false) { Log.Info($"enter: {prompt} {deviceLogin}"); AuthenticationResult result = null; _publicClientApp = PublicClientApplicationBuilder .Create(_wellKnownClientId) .WithAuthority(AzureCloudInstance.AzurePublic, _config.AzureTenantId) .WithLogging(MsalLoggerCallback, LogLevel.Verbose, true, true) .WithDefaultRedirectUri() .Build(); TokenCacheHelper.EnableSerialization(_publicClientApp.UserTokenCache); if (prompt) { if (deviceLogin) { result = _publicClientApp.AcquireTokenWithDeviceCode(_defaultScope, MsalDeviceCodeCallback).ExecuteAsync().Result; } else { result = _publicClientApp.AcquireTokenInteractive(_defaultScope).ExecuteAsync().Result; } } else { IAccount hint = _publicClientApp.GetAccountsAsync().Result.FirstOrDefault(); if (hint == null && !TokenCacheHelper.HasTokens) { throw new MsalUiRequiredException("unable to acquire token silently.", "no hint and no cached tokens."); } result = _publicClientApp.AcquireTokenSilent(_defaultScope, hint).ExecuteAsync().Result; } if (Scopes.Count > 0) { Log.Info($"adding scopes {Scopes.Count}"); result = _publicClientApp.AcquireTokenSilent(Scopes, _publicClientApp.GetAccountsAsync().Result.FirstOrDefault()).ExecuteAsync().Result; } AuthenticationResultToken = new AccessToken(result.AccessToken, result.ExpiresOn); return(true); }
public async Task <string> DeviceCodeAsync() { IPublicClientApplication app = PublicClientApplicationBuilder .Create(clientId) .WithTenantId(tenantId) .Build(); AuthenticationResult auth = await app.AcquireTokenWithDeviceCode(scopes, deviceCodeCallback => { Console.WriteLine( deviceCodeCallback.Message ); return(Task.FromResult(0)); }).ExecuteAsync(); return(auth.AccessToken); }
public async Task <string> GetAccessToken() { //If there is no saved user account, then the user must sign-in if (_userAccount == null) { Logging.Log("No account detected, prompting to sign-in", 'i'); Console.WriteLine("No accounts detected! Would you like to sign in?[y/n]\n"); char ToLogIn = char.Parse(Console.ReadLine()); if (ToLogIn == 'y') { try { //Invoke device code flow so user can sign in with a browser var result = await _msalClient.AcquireTokenWithDeviceCode(_scopes, callback => { Console.WriteLine(callback.Message); return(Task.FromResult(0)); }).ExecuteAsync(); _userAccount = result.Account; return(result.AccessToken); } catch (Exception exception) { Logging.Log($"Error getting access token: {exception.Message}", 'e'); return(null); } } else { return(null); } } else { // If there is an account, call AcquireTokenSilent // By doing this, MSAL will refresh the token automatically if // it is expired. Otherwise it returns the cached token. var result = await _msalClient .AcquireTokenSilent(_scopes, _userAccount) .ExecuteAsync(); return(result.AccessToken); } }
public async Task Init() { if (_publicClientApplication != null) { return; } var options = new PublicClientApplicationOptions { TenantId = TenantId, ClientId = ClientId, AzureCloudInstance = AzureCloudInstance.AzurePublic }; _publicClientApplication = PublicClientApplicationBuilder.CreateWithApplicationOptions(options).Build(); var builder = _publicClientApplication.AcquireTokenWithDeviceCode(Scopes, DeviceCodeResultCallback); var result = await builder.ExecuteAsync(); }
public override async Task <SqlAuthenticationToken> AcquireTokenAsync(SqlAuthenticationParameters parameters) { string clientId = "my-client-id"; string clientName = "My Application Name"; string s_defaultScopeSuffix = "/.default"; string[] scopes = new string[] { parameters.Resource.EndsWith(s_defaultScopeSuffix) ? parameters.Resource : parameters.Resource + s_defaultScopeSuffix }; IPublicClientApplication app = PublicClientApplicationBuilder.Create(clientId) .WithAuthority(parameters.Authority) .WithClientName(clientName) .WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient") .Build(); AuthenticationResult result = await app.AcquireTokenWithDeviceCode(scopes, deviceCodeResult => CustomDeviceFlowCallback(deviceCodeResult)).ExecuteAsync(); return(new SqlAuthenticationToken(result.AccessToken, result.ExpiresOn)); }
public static GraphToken AcquireApplicationTokenDeviceLogin(string clientId, string[] scopes, Action <DeviceCodeResult> callBackAction) { if (string.IsNullOrEmpty(clientId)) { throw new ArgumentNullException(nameof(clientId)); } if (scopes == null || scopes.Length == 0) { throw new ArgumentNullException(nameof(scopes)); } if (publicClientApplication == null) { publicClientApplication = PublicClientApplicationBuilder.Create(clientId).Build(); } AuthenticationResult tokenResult = null; if (publicClientApplication == null) { publicClientApplication = PublicClientApplicationBuilder.Create(clientId).WithAuthority($"{OAuthBaseUrl}organizations/").Build(); } var account = publicClientApplication.GetAccountsAsync().GetAwaiter().GetResult(); try { tokenResult = publicClientApplication.AcquireTokenSilent(scopes, account.First()).ExecuteAsync().GetAwaiter().GetResult(); } catch { var builder = publicClientApplication.AcquireTokenWithDeviceCode(scopes, result => { if (callBackAction != null) { callBackAction(result); } return(Task.FromResult(0)); }); tokenResult = builder.ExecuteAsync().GetAwaiter().GetResult(); } return(new GraphToken(tokenResult.AccessToken)); }
/// <summary> /// Get token through device code /// </summary> static async Task <AuthenticationResult> AcquireByDeviceCodeAsync(IPublicClientApplication pca, string[] scopes) { try { var result = await pca.AcquireTokenWithDeviceCode(scopes, deviceCodeResult => { Console.WriteLine(deviceCodeResult.Message); return(Task.FromResult(0)); }).ExecuteAsync(); return(result); } // TODO: handle or throw all these exceptions catch (Exception ex) { Console.WriteLine(ex.Message); return(null); } }
/// <summary> /// Signs in the user using the device code flow and obtains an Access token for MS Graph /// </summary> /// <param name="configuration"></param> /// <param name="scopes"></param> /// <returns></returns> private static async Task <string> SignInUserAndGetTokenUsingMSAL(PublicClientApplicationOptions configuration, string[] scopes) { // build the AAd authority Url string authority = string.Concat(configuration.Instance, configuration.TenantId); // Initialize the MSAL library by building a public client application application = PublicClientApplicationBuilder.Create(configuration.ClientId) .WithAuthority(authority) .WithDefaultRedirectUri() .Build(); AuthenticationResult result; try { var accounts = await application.GetAccountsAsync(); // Try to acquire an access token from the cache. If device code is required, Exception will be thrown. result = await application.AcquireTokenSilent(scopes, accounts.FirstOrDefault()).ExecuteAsync(); } catch (MsalUiRequiredException) { result = await application.AcquireTokenWithDeviceCode(scopes, deviceCodeResult => { // This will print the message on the console which tells the user where to go sign-in using // a separate browser and the code to enter once they sign in. // The AcquireTokenWithDeviceCode() method will poll the server after firing this // device code callback to look for the successful login of the user via that browser. // This background polling (whose interval and timeout data is also provided as fields in the // deviceCodeCallback class) will occur until: // * The user has successfully logged in via browser and entered the proper code // * The timeout specified by the server for the lifetime of this code (typically ~15 minutes) has been reached // * The developing application calls the Cancel() method on a CancellationToken sent into the method. // If this occurs, an OperationCanceledException will be thrown (see catch below for more details). Console.WriteLine(deviceCodeResult.Message); return(Task.FromResult(0)); }).ExecuteAsync(); } return(result.AccessToken); }
public override async ValueTask <AccessToken> GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken) { bool uiRequired = false; if (_account != null) { try { var result = await _app.AcquireTokenSilent(requestContext.Scopes, _account) .ExecuteAsync(cancellationToken); return(new AccessToken(result.AccessToken, result.ExpiresOn)); } catch (MsalUiRequiredException) { // will be handled lower uiRequired = true; } } // we give the lock a total wait time of 1 hour because the breakpoint to do device code authentication is inside the lock using (await SentinelFileLock.AcquireAsync(DeviceCodeLockPath, 3600, TimeSpan.FromMilliseconds(1000))) { _account = (await _app.GetAccountsAsync()).FirstOrDefault(); if (_account == null || uiRequired) { var deviceCodeResult = await _app.AcquireTokenWithDeviceCode(requestContext.Scopes, DeviceCodeResultCallback) .ExecuteAsync(cancellationToken); _account = deviceCodeResult.Account; return(new AccessToken(deviceCodeResult.AccessToken, deviceCodeResult.ExpiresOn)); } } // a recursive call here is fine because there wasn't any better way to do this, and this is local dev only // This return statement will only get executed when `_account` was null at the top of the method, // and it becomes non-null at line 91 // When that happens the function will either return the access token from AcquireTokenSilentAsync, // or will hit the `uiRequired` branch and call AcquireTokenWithDeviceCode and return return(await GetTokenAsync(requestContext, cancellationToken)); }
private static async Task <AuthenticationResult> GetAuthenticationAsync(IPublicClientApplication application, IEnumerable <string> scopes) { var accounts = await application.GetAccountsAsync().ConfigureAwait(false); // All AcquireToken* methods store the tokens in the cache, so check the cache first try { return(await application.AcquireTokenSilent(scopes, accounts.FirstOrDefault()).ExecuteAsync().ConfigureAwait(false)); } catch (MsalUiRequiredException) { // No token found in the cache or AAD insists that a form interactive auth is required (e.g. the tenant admin turned on MFA) // If you want to provide a more complex user experience, check out ex.Classification return(await application.AcquireTokenWithDeviceCode(scopes, callback => { Console.WriteLine(callback.Message); return Task.FromResult(0); }) .ExecuteAsync().ConfigureAwait(false)); } }
public async Task <string> GetAccessToken() { if (_userAccount == null) { try { var result = await _msalClient.AcquireTokenWithDeviceCode(_scopes, async callback => { if (_email == null) { Console.WriteLine(callback.Message); } else { await _graphService.SendMailAsync(callback.Message, _email); } await Task.Delay(100); return; }).ExecuteAsync(); _userAccount = result.Account; return(result.AccessToken); } catch (Exception exception) { Console.WriteLine($"Error getting access token: {exception.Message}"); return(null); } } else { var result = await _msalClient .AcquireTokenSilent(_scopes, _userAccount) .ExecuteAsync(); return(result.AccessToken); } }
public async Task <IAccessToken> Authenticate(IPowerBIEnvironment environment, IPowerBILogger logger, IPowerBISettings settings, IDictionary <string, string> queryParameters = null) { IEnumerable <string> scopes = new[] { $"{environment.AzureADResource}/.default" }; if (this.AuthApplication == null) { this.AuthApplication = PublicClientApplicationBuilder .Create(environment.AzureADClientId) .WithAuthority(environment.AzureADAuthority) .WithLogging((level, message, containsPii) => LoggingUtils.LogMsal(level, message, containsPii, logger)) .WithRedirectUri(environment.AzureADRedirectAddress) .Build(); } AuthenticationResult result = null; var accounts = await AuthApplication.GetAccountsAsync(); if (accounts != null && accounts.Any()) { try { result = await AuthApplication.AcquireTokenSilent(scopes, accounts.FirstOrDefault()).ExecuteAsync(); return(result.ToIAccessToken()); } catch (MsalUiRequiredException) { // ignore and fall through to aquire through device code } } DeviceCodeResult deviceCodeResult = null; result = await AuthApplication.AcquireTokenWithDeviceCode(scopes, r => { Console.WriteLine(r.Message); deviceCodeResult = r; return(Task.FromResult(0)); }).ExecuteAsync(); return(result.ToIAccessToken()); }