private async ValueTask <AccessToken> GetTokenImplAsync(TokenRequestContext requestContext, bool async, CancellationToken cancellationToken) { using CredentialDiagnosticScope scope = _pipeline.StartGetTokenScope("VisualStudioCredential.GetToken", requestContext); try { var tokenProviderPath = GetTokenProviderPath(); var tokenProviders = GetTokenProviders(tokenProviderPath); var resource = ScopeUtilities.ScopesToResource(requestContext.Scopes); var processStartInfos = GetProcessStartInfos(tokenProviders, resource, cancellationToken); if (processStartInfos.Count == 0) { throw new CredentialUnavailableException("No installed instance of Visual Studio was found"); } return(await RunProcessesAsync(processStartInfos, async, cancellationToken).ConfigureAwait(false)); } catch (OperationCanceledException e) { scope.Failed(e); throw; } catch (Exception e) { throw scope.FailAndWrap(e); } }
protected override Request CreateRequest(string[] scopes) { // covert the scopes to a resource string string resource = ScopeUtilities.ScopesToResource(scopes); Request request = Pipeline.HttpPipeline.CreateRequest(); request.Method = RequestMethod.Get; request.Headers.Add("Metadata", "true"); request.Uri.Reset(_imdsEndpoint); request.Uri.AppendQuery("api-version", ImdsApiVersion); request.Uri.AppendQuery("resource", resource); if (!string.IsNullOrEmpty(_clientId)) { request.Uri.AppendQuery(Constants.ManagedIdentityClientId, _clientId); } if (!string.IsNullOrEmpty(_resourceId)) { request.Uri.AppendQuery(Constants.ManagedIdentityResourceId, _resourceId); } return(request); }
protected virtual async ValueTask <AccessToken> RequestCliAccessTokenAsync(bool async, string[] scopes, CancellationToken cancellationToken) { string resource = ScopeUtilities.ScopesToResource(scopes); ScopeUtilities.ValidateScope(resource); (string output, int exitCode) = await GetAzureCliAccesToken(async, resource, cancellationToken).ConfigureAwait(false); if (exitCode != 0) { bool isLoginError = output.IndexOf("az login", StringComparison.OrdinalIgnoreCase) != -1 || output.IndexOf("az account set", StringComparison.OrdinalIgnoreCase) != -1; bool isWinError = output.StartsWith(WinAzureCLIError, StringComparison.CurrentCultureIgnoreCase); bool isOtherOsError = AzNotFoundPattern.IsMatch(output); if (isWinError || isOtherOsError) { throw new CredentialUnavailableException(AzureCLINotInstalled); } else if (isLoginError) { throw new CredentialUnavailableException(AzNotLogIn); } throw new AuthenticationFailedException($"{AzureCliFailedError} {output}"); } return(DeserializeOutput(output)); }
private Request CreateManagedIdentityAuthRequest(string[] scopes, string clientId = null) { // covert the scopes to a resource string string resource = ScopeUtilities.ScopesToResource(scopes); Request request = _pipeline.CreateRequest(); request.Method = HttpPipelineMethod.Get; request.Headers.Add("Metadata", "true"); // TODO: support MSI for hosted services request.UriBuilder.Uri = ImdsEndptoint; request.UriBuilder.AppendQuery("api-version", MsiApiVersion); request.UriBuilder.AppendQuery("resource", Uri.EscapeDataString(resource)); if (!string.IsNullOrEmpty(clientId)) { request.UriBuilder.AppendQuery("client_id", Uri.EscapeDataString(clientId)); } return(request); }
private async ValueTask <AccessToken> RequestCliAccessTokenAsync(bool async, TokenRequestContext context, CancellationToken cancellationToken) { string resource = ScopeUtilities.ScopesToResource(context.Scopes); string tenantId = TenantIdResolver.Resolve(_tenantId, context, _allowMultiTenantAuthentication); ScopeUtilities.ValidateScope(resource); GetFileNameAndArguments(resource, tenantId, out string fileName, out string argument); ProcessStartInfo processStartInfo = GetAzureCliProcessStartInfo(fileName, argument); using var processRunner = new ProcessRunner(_processService.Create(processStartInfo), TimeSpan.FromMilliseconds(CliProcessTimeoutMs), cancellationToken); string output; try { output = async ? await processRunner.RunAsync().ConfigureAwait(false) : processRunner.Run(); } catch (OperationCanceledException) when(!cancellationToken.IsCancellationRequested) { throw new AuthenticationFailedException(AzureCliTimeoutError); } catch (InvalidOperationException exception) { bool isWinError = exception.Message.StartsWith(WinAzureCLIError, StringComparison.CurrentCultureIgnoreCase); bool isOtherOsError = AzNotFoundPattern.IsMatch(exception.Message); if (isWinError || isOtherOsError) { throw new CredentialUnavailableException(AzureCLINotInstalled); } bool isLoginError = exception.Message.IndexOf("az login", StringComparison.OrdinalIgnoreCase) != -1 || exception.Message.IndexOf("az account set", StringComparison.OrdinalIgnoreCase) != -1; if (isLoginError) { throw new CredentialUnavailableException(AzNotLogIn); } bool isRefreshTokenFailedError = exception.Message.IndexOf(AzureCliFailedError, StringComparison.OrdinalIgnoreCase) != -1 && exception.Message.IndexOf(RefreshTokeExpired, StringComparison.OrdinalIgnoreCase) != -1 || exception.Message.IndexOf("CLIInternalError", StringComparison.OrdinalIgnoreCase) != -1; if (isRefreshTokenFailedError) { throw new CredentialUnavailableException(InteractiveLoginRequired); } throw new AuthenticationFailedException($"{AzureCliFailedError} {exception.Message}"); } return(DeserializeOutput(output)); }
private async ValueTask <AccessToken> RequestAzurePowerShellAccessTokenAsync(bool async, TokenRequestContext context, CancellationToken cancellationToken) { string resource = ScopeUtilities.ScopesToResource(context.Scopes); ScopeUtilities.ValidateScope(resource); var tenantId = TenantIdResolver.Resolve(_tenantId, context, _allowMultiTenantAuthentication); GetFileNameAndArguments(resource, tenantId, out string fileName, out string argument); ProcessStartInfo processStartInfo = GetAzurePowerShellProcessStartInfo(fileName, argument); using var processRunner = new ProcessRunner( _processService.Create(processStartInfo), TimeSpan.FromMilliseconds(PowerShellProcessTimeoutMs), _logPII, cancellationToken); string output; try { output = async ? await processRunner.RunAsync().ConfigureAwait(false) : processRunner.Run(); CheckForErrors(output); } catch (OperationCanceledException) when(!cancellationToken.IsCancellationRequested) { throw new AuthenticationFailedException(AzurePowerShellTimeoutError); } catch (InvalidOperationException exception) { bool noPowerShell = exception.Message.IndexOf("not found", StringComparison.OrdinalIgnoreCase) != -1 || exception.Message.IndexOf("is not recognized", StringComparison.OrdinalIgnoreCase) != -1; if (noPowerShell) { throw new CredentialUnavailableException(PowerShellNotInstalledError); } bool noLogin = exception.Message.IndexOf("Run Connect-AzAccount to login", StringComparison.OrdinalIgnoreCase) != -1; if (noLogin) { throw new CredentialUnavailableException(AzurePowerShellNotLogInError); } throw new AuthenticationFailedException($"{AzurePowerShellFailedError} {exception.Message}"); } return(DeserializeOutput(output)); }
protected override Request CreateRequest(string[] scopes) { // covert the scopes to a resource string string resource = ScopeUtilities.ScopesToResource(scopes); Request request = Pipeline.HttpPipeline.CreateRequest(); request.Method = RequestMethod.Post; request.Headers.Add(HttpHeader.Common.FormUrlEncodedContentType); request.Uri.Reset(_endpoint); request.Headers.Add("Metadata", "true"); var bodyStr = $"resource={Uri.EscapeDataString(resource)}"; ReadOnlyMemory<byte> content = Encoding.UTF8.GetBytes(bodyStr).AsMemory(); request.Content = RequestContent.Create(content); return request; }
private async ValueTask <AccessToken> RequestAzurePowerShellAccessTokenAsync(bool async, TokenRequestContext context, CancellationToken cancellationToken) { string resource = ScopeUtilities.ScopesToResource(context.Scopes); ScopeUtilities.ValidateScope(resource); var tenantId = TenantIdResolver.Resolve(_tenantId, context); GetFileNameAndArguments(resource, tenantId, out string fileName, out string argument); ProcessStartInfo processStartInfo = GetAzurePowerShellProcessStartInfo(fileName, argument); using var processRunner = new ProcessRunner( _processService.Create(processStartInfo), TimeSpan.FromMilliseconds(PowerShellProcessTimeoutMs), _logPII, cancellationToken); string output; try { output = async ? await processRunner.RunAsync().ConfigureAwait(false) : processRunner.Run(); CheckForErrors(output); ValidateResult(output); } catch (OperationCanceledException) when(!cancellationToken.IsCancellationRequested) { throw new AuthenticationFailedException(AzurePowerShellTimeoutError); } catch (InvalidOperationException exception) { CheckForErrors(exception.Message); throw new AuthenticationFailedException($"{AzurePowerShellFailedError} {exception.Message}"); } return(DeserializeOutput(output)); }