src/Authentication/MsalDeviceCodeTokenProvider.cs (39 lines of code) (raw):

// Copyright (c) Microsoft. All rights reserved. // // Licensed under the MIT license. using Microsoft.Extensions.Logging; using Microsoft.Identity.Client; namespace Microsoft.Artifacts.Authentication; public class MsalDeviceCodeTokenProvider : ITokenProvider { private readonly IPublicClientApplication app; private readonly ILogger logger; public MsalDeviceCodeTokenProvider(IPublicClientApplication app, ILogger logger) { this.app = app ?? throw new ArgumentNullException(nameof(app)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); } public string Name => "MSAL Device Code"; public bool IsInteractive => true; public bool CanGetToken(TokenRequest tokenRequest) { return tokenRequest.IsInteractive; } public async Task<AuthenticationResult?> GetTokenAsync(TokenRequest tokenRequest, CancellationToken cancellationToken = default) { using CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); cts.CancelAfter(tokenRequest.InteractiveTimeout); try { var result = await app.AcquireTokenWithDeviceCode(MsalConstants.AzureDevOpsScopes, tokenRequest.DeviceCodeResultCallback ?? ((DeviceCodeResult deviceCodeResult) => { logger.LogInformation(deviceCodeResult.Message); return Task.CompletedTask; })) .ExecuteAsync(cts.Token); return result; } catch (OperationCanceledException ex) when (cts.IsCancellationRequested) { logger.LogWarning(ex.Message); return null; } } }