/// <inheritdoc/> public override void DeleteCredentials(TargetUri targetUri, string username) { BaseSecureStore.ValidateTargetUri(targetUri); Trace.WriteLine($"Deleting Bitbucket Credentials for {targetUri.QueryUri}"); Credential credentials = null; if ((credentials = PersonalAccessTokenStore.ReadCredentials(targetUri)) != null) { // try to delete the credentials for the explicit target uri first PersonalAccessTokenStore.DeleteCredentials(targetUri); Trace.WriteLine($"host credentials deleted for {targetUri.QueryUri}"); } // tidy up and delete any related refresh tokens var refreshTargetUri = GetRefreshTokenTargetUri(targetUri); if ((credentials = PersonalAccessTokenStore.ReadCredentials(refreshTargetUri)) != null) { // try to delete the credentials for the explicit target uri first PersonalAccessTokenStore.DeleteCredentials(refreshTargetUri); Trace.WriteLine($"host refresh credentials deleted for {refreshTargetUri.QueryUri}"); } // if we deleted per user then we should try and delete the host level credentials too if // they match the username if (targetUri.TargetUriContainsUsername) { var hostTargetUri = new TargetUri(targetUri.ToString(false, true, true)); var hostCredentials = GetCredentials(hostTargetUri); var encodedUsername = Uri.EscapeDataString(targetUri.TargetUriUsername); if (encodedUsername != username) { Trace.WriteLine($"username {username} != targetUri userInfo {encodedUsername}"); } if (hostCredentials != null && hostCredentials.Username.Equals(encodedUsername)) { DeleteCredentials(hostTargetUri, username); } } }
/// <inheritdoc/> public async Task <Credential> ValidateCredentials(TargetUri targetUri, string username, Credential credentials) { BaseSecureStore.ValidateTargetUri(targetUri); BaseSecureStore.ValidateCredential(credentials); TargetUri userSpecificTargetUri; if (targetUri.TargetUriContainsUsername) { userSpecificTargetUri = targetUri; } else { userSpecificTargetUri = targetUri.GetPerUserTargetUri(username); } if (await BitbucketAuthority.ValidateCredentials(userSpecificTargetUri, username, credentials)) { return(credentials); } var userSpecificRefreshCredentials = GetCredentials(GetRefreshTokenTargetUri(userSpecificTargetUri), username); // if there are refresh credentials it suggests it might be OAuth so we can try and // refresh the access_token and try again. if (userSpecificRefreshCredentials == null) { return(null); } Credential refreshedCredentials; if ((refreshedCredentials = await RefreshCredentials(userSpecificTargetUri, userSpecificRefreshCredentials.Password, username ?? credentials.Username)) != null) { return(refreshedCredentials); } return(null); }
/// <summary> /// Creates an interactive logon session, using ADAL secure browser GUI, which enables users to authenticate with the Azure tenant and acquire the necessary access tokens to exchange for a VSTS personal access token. /// <para/> /// Tokens acquired are stored in the secure secret stores provided during initialization. /// <para/> /// Return a `<see cref="Credential"/>` for resource access if successful; otherwise `<see langword="null"/>`. /// </summary> /// <param name="targetUri">The URI of the VSTS resource.</param> public async Task <Credential> InteractiveLogon(TargetUri targetUri, PersonalAccessTokenOptions options) { BaseSecureStore.ValidateTargetUri(targetUri); try { Token token; if ((token = await Authority.InteractiveAcquireToken(targetUri, ClientId, Resource, new Uri(RedirectUrl), null)) != null) { Trace.WriteLine($"token acquisition for '{targetUri}' succeeded."); return(await GeneratePersonalAccessToken(targetUri, token, options)); } } catch (AuthenticationException) { Trace.WriteLine($"token acquisition for '{targetUri}' failed."); } Trace.WriteLine($"interactive logon for '{targetUri}' failed"); return(null); }
public async Task <Credential> NoninteractiveLogon(TargetUri targetUri, bool requestCompactToken) { BaseSecureStore.ValidateTargetUri(targetUri); try { Token token; if ((token = await Authority.NoninteractiveAcquireToken(targetUri, ClientId, Resource, new Uri(RedirectUrl))) != null) { Trace.WriteLine($"token acquisition for '{targetUri}' succeeded"); return(await GeneratePersonalAccessToken(targetUri, token, requestCompactToken)); } } catch (AuthenticationException) { Trace.WriteLine($"failed to acquire for '{targetUri}' token from VstsAuthority."); } Trace.WriteLine($"non-interactive logon for '{targetUri}' failed"); return(null); }
/// <summary> /// Opens an interactive logon prompt to acquire an authentication token from the Microsoft Live authentication and identity service. /// <para/> /// Returns a `<see cref="Credential"/>` for packing into a basic authentication header; otherwise `<see langword="null"/>`. /// </summary> /// <param name="targetUri">The URI of the resource access is being requested for.</param> /// <param name="requestCompactToken">`<see langword="true"/>` if requesting a compact format token; otherwise `<see langword="false"/>`.</param> public async Task <Credential> InteractiveLogon(TargetUri targetUri, bool requestCompactToken) { BaseSecureStore.ValidateTargetUri(targetUri); try { Token token; if ((token = await Authority.InteractiveAcquireToken(targetUri, ClientId, Resource, new Uri(RedirectUrl), QueryParameters)) != null) { Trace.WriteLine($"token '{targetUri}' successfully acquired."); return(await GeneratePersonalAccessToken(targetUri, token, requestCompactToken)); } } catch (AuthenticationException exception) { Debug.Write(exception); } Trace.WriteLine($"failed to acquire token for '{targetUri}'."); return(null); }
public async Task <bool> ValidateCredentials(TargetUri targetUri, Credential credentials) { const string ValidationUrl = "https://api.github.com/user/subscriptions"; BaseSecureStore.ValidateTargetUri(targetUri); BaseSecureStore.ValidateCredential(credentials); string authString = String.Format("{0}:{1}", credentials.Username, credentials.Password); byte[] authBytes = Encoding.UTF8.GetBytes(authString); string authEncode = Convert.ToBase64String(authBytes); // craft the request header for the GitHub v3 API w/ credentials using (HttpClientHandler handler = targetUri.HttpClientHandler) using (HttpClient httpClient = new HttpClient(handler) { Timeout = TimeSpan.FromMilliseconds(RequestTimeout) }) { httpClient.DefaultRequestHeaders.Add("User-Agent", Global.UserAgent); httpClient.DefaultRequestHeaders.Add("Accept", GitHubApiAcceptsHeaderValue); httpClient.DefaultRequestHeaders.Add("Authorization", "Basic " + authEncode); using (HttpResponseMessage response = await httpClient.GetAsync(ValidationUrl)) { if (response.IsSuccessStatusCode) { Git.Trace.WriteLine($"credential validation for '{targetUri}' succeeded."); return(true); } else { Git.Trace.WriteLine($"credential validation for '{targetUri}' failed."); return(false); } } } }
/// <summary> /// Identify the Hosting service from the the targetUri. /// </summary> /// <param name="targetUri"></param> /// <returns> /// A <see cref="BaseAuthentication"/> instance if the targetUri represents Bitbucket, null otherwise. /// </returns> public static BaseAuthentication GetAuthentication(TargetUri targetUri, ICredentialStore personalAccessTokenStore, AcquireCredentialsDelegate acquireCredentialsCallback, AcquireAuthenticationOAuthDelegate acquireAuthenticationOAuthCallback) { BaseAuthentication authentication = null; BaseSecureStore.ValidateTargetUri(targetUri); if (personalAccessTokenStore == null) { throw new ArgumentNullException(nameof(personalAccessTokenStore), $"The `{nameof(personalAccessTokenStore)}` is null or invalid."); } if (targetUri.QueryUri.DnsSafeHost.EndsWith(BitbucketBaseUrlHost, StringComparison.OrdinalIgnoreCase)) { authentication = new Authentication(personalAccessTokenStore, acquireCredentialsCallback, acquireAuthenticationOAuthCallback); Trace.WriteLine("authentication for Bitbucket created"); } else { authentication = null; } return(authentication); }
/// <summary> /// Gets a configured authentication object for 'github.com'. /// </summary> /// <param name="targetUri"> /// The uniform resource indicator of the resource which requires authentication. /// </param> /// <param name="tokenScope">The desired scope of any personal access tokens acquired.</param> /// <param name="personalAccessTokenStore"> /// A secure secret store for any personal access tokens acquired. /// </param> /// <param name="authentication">(out) The authentication object if successful.</param> /// <returns>True if success; otherwise false.</returns> public static BaseAuthentication GetAuthentication( RuntimeContext context, TargetUri targetUri, TokenScope tokenScope, ICredentialStore personalAccessTokenStore, AcquireCredentialsDelegate acquireCredentialsCallback, AcquireAuthenticationCodeDelegate acquireAuthenticationCodeCallback, AuthenticationResultDelegate authenticationResultCallback) { BaseAuthentication authentication = null; BaseSecureStore.ValidateTargetUri(targetUri); if (personalAccessTokenStore == null) { throw new ArgumentNullException("personalAccessTokenStore", "The `personalAccessTokenStore` is null or invalid."); } if (targetUri.DnsSafeHost.EndsWith(GitHubBaseUrlHost, StringComparison.OrdinalIgnoreCase)) { var normalizedTargetUri = NormalizeUri(targetUri); authentication = new Authentication(context, normalizedTargetUri, tokenScope, personalAccessTokenStore, acquireCredentialsCallback, acquireAuthenticationCodeCallback, authenticationResultCallback); context.Trace.WriteLine($"created GitHub authentication for '{normalizedTargetUri}'."); } else { authentication = null; context.Trace.WriteLine($"not github.com, authentication creation aborted."); } return(authentication); }
/// <inheritdoc/> public async Task <bool> ValidateCredentials(TargetUri targetUri, string username, Credential credentials) { BaseSecureStore.ValidateTargetUri(targetUri); BaseSecureStore.ValidateCredential(credentials); // We don't know when the credentials arrive here if they are using OAuth or Basic Auth, // so we try both. // Try the simplest Basic Auth first var authEncode = GetEncodedCredentials(username, credentials); if (await ValidateCredentials(targetUri, GetBasicAuthHeader(authEncode))) { return(true); } // if the Basic Auth test failed then try again as OAuth if (await ValidateCredentials(targetUri, GetBearerHeaderAuthHeader(credentials.Password))) { return(true); } return(false); }
/// <inheritdoc/> public async Task <bool> ValidateCredentials(TargetUri targetUri, string username, Credential credentials) { BaseSecureStore.ValidateTargetUri(targetUri); BaseSecureStore.ValidateCredential(credentials); // We don't know when the credentials arrive here if they are using OAuth or Basic Auth, // so we try both. // Try the simplest basic authentication first var authEncode = GetEncodedCredentials(username, credentials); if (await ValidateCredentials(targetUri, credentials)) { return(true); } // If the basic authentication test failed then try again as OAuth if (await ValidateCredentials(targetUri, new Token(credentials.Password, TokenType.BitbucketPassword))) { return(true); } return(false); }