using System; using Microsoft.IdentityModel.Clients.ActiveDirectory; using GitHub.Services.Common; namespace GitHub.Services.Client { [Serializable] public class VssAadToken : IssuedToken { private string accessToken; private string accessTokenType; private AuthenticationContext authenticationContext; private UserCredential userCredential; private VssAadTokenOptions options; public VssAadToken(AuthenticationResult authentication) { // Prevent any attempt to store this token. this.FromStorage = true; if (!string.IsNullOrWhiteSpace(authentication.AccessToken)) { this.Authenticated(); } this.accessToken = authentication.AccessToken; this.accessTokenType = authentication.AccessTokenType; } public VssAadToken( string accessTokenType, string accessToken) { // Prevent any attempt to store this token. this.FromStorage = true; if (!string.IsNullOrWhiteSpace(accessToken) && !string.IsNullOrWhiteSpace(accessTokenType)) { this.Authenticated(); } this.accessToken = accessToken; this.accessTokenType = accessTokenType; } public VssAadToken( AuthenticationContext authenticationContext, UserCredential userCredential = null, VssAadTokenOptions options = VssAadTokenOptions.None) { // Prevent any attempt to store this token. this.FromStorage = true; this.authenticationContext = authenticationContext; this.userCredential = userCredential; this.options = options; } protected internal override VssCredentialsType CredentialType { get { return VssCredentialsType.Aad; } } public AuthenticationResult AcquireToken() { if (this.authenticationContext == null) { return null; } AuthenticationResult authenticationResult = null; for (int index = 0; index < 3; index++) { try { if (this.userCredential == null && !options.HasFlag(VssAadTokenOptions.AllowDialog)) { authenticationResult = authenticationContext.AcquireTokenSilentAsync(VssAadSettings.Resource, VssAadSettings.Client).ConfigureAwait(false).GetAwaiter().GetResult(); } else { authenticationResult = authenticationContext.AcquireTokenAsync(VssAadSettings.Resource, VssAadSettings.Client, this.userCredential).ConfigureAwait(false).GetAwaiter().GetResult(); } if (authenticationResult != null) { break; } } catch (Exception x) { System.Diagnostics.Debug.WriteLine("Failed to get ADFS token: " + x.ToString()); } } return authenticationResult; } internal override void ApplyTo(IHttpRequest request) { AuthenticationResult authenticationResult = AcquireToken(); if (authenticationResult != null) { request.Headers.SetValue(Common.Internal.HttpHeaders.Authorization, $"{authenticationResult.AccessTokenType} {authenticationResult.AccessToken}"); } else if (!string.IsNullOrEmpty(this.accessTokenType) && !string.IsNullOrEmpty(this.accessToken)) { request.Headers.SetValue(Common.Internal.HttpHeaders.Authorization, $"{this.accessTokenType} {this.accessToken}"); } } } [Flags] public enum VssAadTokenOptions { None = 0, AllowDialog = 1 } }