public VstsMsaAuthentication( RuntimeContext context, VstsTokenScope tokenScope, ICredentialStore personalAccessTokenStore) : base(context, tokenScope, personalAccessTokenStore) { VstsAuthority = new VstsAzureAuthority(context, DefaultAuthorityHost); }
protected BaseVstsAuthentication(VstsTokenScope tokenScope, ICredentialStore personalAccessTokenStore) { if (tokenScope is null) { throw new ArgumentNullException(nameof(tokenScope)); } if (personalAccessTokenStore is null) { throw new ArgumentNullException(nameof(personalAccessTokenStore)); } ClientId = DefaultClientId; Resource = DefaultResource; TokenScope = tokenScope; PersonalAccessTokenStore = personalAccessTokenStore; VstsAuthority = new VstsAzureAuthority(); }
/// <summary> /// </summary> /// <param name="tenantId"> /// <para>The unique identifier for the responsible Azure tenant.</para> /// <para> /// Use <see cref="BaseVstsAuthentication.GetAuthentication"/> to detect the tenant identity /// and create the authentication object. /// </para> /// </param> /// <param name="tokenScope">The scope of all access tokens acquired by the authority.</param> /// <param name="personalAccessTokenStore"> /// The secure secret store for storing any personal access tokens acquired. /// </param> /// <param name="adaRefreshTokenStore"> /// The secure secret store for storing any Azure tokens acquired. /// </param> public VstsAadAuthentication( Guid tenantId, VstsTokenScope tokenScope, ICredentialStore personalAccessTokenStore) : base(tokenScope, personalAccessTokenStore) { if (tenantId == Guid.Empty) { VstsAuthority = new VstsAzureAuthority(AzureAuthority.DefaultAuthorityHostUrl); } else { // create an authority host URL in the format of https://login.microsoft.com/12345678-9ABC-DEF0-1234-56789ABCDEF0 string authorityHost = AzureAuthority.GetAuthorityUrl(tenantId); VstsAuthority = new VstsAzureAuthority(authorityHost); } }
public static async Task <Guid?> DetectAuthority(RuntimeContext context, TargetUri targetUri) { const string VstsResourceTenantHeader = "X-VSS-ResourceTenant"; if (context is null) { throw new ArgumentNullException(nameof(context)); } if (targetUri is null) { throw new ArgumentNullException(nameof(targetUri)); } var tenantId = Guid.Empty; if (VstsAzureAuthority.IsVstsUrl(targetUri)) { var tenantUrl = VstsAzureAuthority.GetTargetUrl(targetUri); context.Trace.WriteLine($"'{targetUri}' is a member '{tenantUrl}', checking AAD vs MSA."); if (StringComparer.OrdinalIgnoreCase.Equals(targetUri.Scheme, Uri.UriSchemeHttp) || StringComparer.OrdinalIgnoreCase.Equals(targetUri.Scheme, Uri.UriSchemeHttps)) { // Read the cache from disk. var cache = await DeserializeTenantCache(context); // Check the cache for an existing value. if (cache.TryGetValue(tenantUrl, out tenantId)) { return(tenantId); } var options = new NetworkRequestOptions(false) { Flags = NetworkRequestOptionFlags.UseProxy, Timeout = TimeSpan.FromMilliseconds(Global.RequestTimeout), }; try { var tenantUri = new TargetUri(tenantUrl, targetUri.ProxyUri?.ToString()); using (var response = await context.Network.HttpHeadAsync(tenantUri, options)) { if (response.Headers != null && response.Headers.TryGetValues(VstsResourceTenantHeader, out IEnumerable <string> values)) { foreach (string value in values) { // Try to find a non-empty value for the resource-tenant identity if (!string.IsNullOrWhiteSpace(value) && Guid.TryParse(value, out tenantId) && tenantId != Guid.Empty) { // Update the cache. cache[tenantUrl] = tenantId; // Write the cache to disk. await SerializeTenantCache(context, cache); // Success, notify the caller return(tenantId); } } // Since we did not find a better identity, fallback to the default (Guid.Empty). return(tenantId); } else { context.Trace.WriteLine($"unable to get response from '{targetUri}' [{(int)response.StatusCode} {response.StatusCode}]."); } } } catch (HttpRequestException exception) { context.Trace.WriteLine($"unable to get response from '{targetUri}', an error occurred before the server could respond."); context.Trace.WriteException(exception); } } else { context.Trace.WriteLine($"detected non-http(s) based protocol: '{targetUri.Scheme}'."); } } if (StringComparer.OrdinalIgnoreCase.Equals(VstsBaseUrlHost, targetUri.Host)) { return(Guid.Empty); } // Fallback to basic authentication. return(null); }
public VstsMsaAuthentication(VstsTokenScope tokenScope, ICredentialStore personalAccessTokenStore) : base(tokenScope, personalAccessTokenStore) { VstsAuthority = new VstsAzureAuthority(DefaultAuthorityHost); }