/// <summary> /// Call the plugin credential provider application to acquire credentials. /// The request will be passed to the plugin on standard input as a json serialized /// PluginCredentialRequest. /// The plugin will return credentials as a json serialized PluginCredentialResponse. /// Valid credentials will be returned, or null if the provide cannot provide credentials /// for the given request. If the plugin returns an Abort message, an exception will be thrown to /// fail the current request. /// </summary> /// <param name="uri">The uri of a web resource for which credentials are needed.</param> /// <param name="proxy">Ignored. Proxy information will not be passed to plugins.</param> /// <param name="type"> /// The type of credential request that is being made. Note that this implementation of /// <see cref="ICredentialProvider"/> does not support providing proxy credenitials and treats /// all other types the same. /// </param> /// <param name="isRetry">If true, credentials were previously supplied by this /// provider for the same uri.</param> /// <param name="message">A message provided by NuGet to show to the user when prompting.</param> /// <param name="nonInteractive">If true, the plugin must not prompt for credentials.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <returns>A credential object. If </returns> public Task <CredentialResponse> GetAsync( Uri uri, IWebProxy proxy, CredentialRequestType type, string message, bool isRetry, bool nonInteractive, CancellationToken cancellationToken) { CredentialResponse taskResponse; if (type == CredentialRequestType.Proxy) { taskResponse = new CredentialResponse(CredentialStatus.ProviderNotApplicable); return(Task.FromResult(taskResponse)); } try { var request = new PluginCredentialRequest { Uri = uri.ToString(), IsRetry = isRetry, NonInteractive = nonInteractive }; // TODO: Extend the plug protocol to pass in the credential request type. var response = Execute(request, cancellationToken); if (response.IsValid) { ICredentials result = new NetworkCredential(response.Username, response.Password); if (response.AuthTypes != null) { result = new AuthTypeFilteredCredentials(result, response.AuthTypes); } taskResponse = new CredentialResponse(result); } else { taskResponse = new CredentialResponse(CredentialStatus.ProviderNotApplicable); } } catch (OperationCanceledException) { throw; } catch (PluginException) { throw; } catch (Exception e) { throw PluginException.Create(Path, e); } return(Task.FromResult(taskResponse)); }
/// <param name="uri">The uri of a web resource for which credentials are needed.</param> /// <param name="proxy">Ignored. Proxy information will not be passed to plugins.</param> /// <param name="type"> /// The type of credential request that is being made. Note that this implementation of /// <see cref="ICredentialProvider"/> does not support providing proxy credenitials and treats /// all other types the same. /// </param> /// <param name="isRetry">If true, credentials were previously supplied by this /// provider for the same uri.</param> /// <param name="message">A message provided by NuGet to show to the user when prompting.</param> /// <param name="nonInteractive">If true, the plugin must not prompt for credentials.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <returns>A credential object.</returns> public async Task <CredentialResponse> GetAsync(Uri uri, IWebProxy proxy, CredentialRequestType type, string message, bool isRetry, bool nonInteractive, CancellationToken cancellationToken) { CredentialResponse taskResponse = null; if (type == CredentialRequestType.Proxy || !_isAnAuthenticationPlugin) { taskResponse = new CredentialResponse(CredentialStatus.ProviderNotApplicable); return(taskResponse); } var plugin = await _pluginManager.CreateSourceAgnosticPluginAsync(_discoveredPlugin, cancellationToken); if (!string.IsNullOrEmpty(plugin.Message)) { // There is a potential here for double logging as the CredentialService itself catches the exceptions and tries to log it. // In reality the logger in the Credential Service will be null because the first request always comes from a resource provider (ServiceIndex provider) _logger.LogError(plugin.Message); throw new PluginException(plugin.Message); // Throwing here will block authentication and ensure that the complete operation fails } _isAnAuthenticationPlugin = plugin.Claims.Contains(OperationClaim.Authentication); if (_isAnAuthenticationPlugin) { AddOrUpdateLogger(plugin.Plugin); await SetPluginLogLevelAsync(plugin, _logger, cancellationToken); if (proxy != null) { await SetProxyCredentialsToPlugin(uri, proxy, plugin, cancellationToken); } var request = new GetAuthenticationCredentialsRequest(uri, isRetry, nonInteractive); var credentialResponse = await plugin.Plugin.Connection.SendRequestAndReceiveResponseAsync <GetAuthenticationCredentialsRequest, GetAuthenticationCredentialsResponse>( MessageMethod.GetAuthenticationCredentials, request, cancellationToken); if (credentialResponse.ResponseCode == MessageResponseCode.NotFound && nonInteractive) { _logger.LogWarning( string.Format( CultureInfo.CurrentCulture, Resources.SecurePluginWarning_UseInteractiveOption) ); } taskResponse = GetAuthenticationCredentialsResponseToCredentialResponse(credentialResponse); } else { taskResponse = new CredentialResponse(CredentialStatus.ProviderNotApplicable); } return(taskResponse); }
bool TryFromCredentialCache(Uri uri, CredentialRequestType type, bool isRetry, ICredentialProvider provider, out CredentialResponse credentials) { credentials = null; var key = CredentialCacheKey(uri, type, provider); if (isRetry) { CredentialResponse removed; _providerCredentialCache.TryRemove(key, out removed); return(false); } return(_providerCredentialCache.TryGetValue(key, out credentials)); }
/// <summary> /// Convert from Plugin CredentialResponse to the CredentialResponse model used by the ICredentialService /// </summary> /// <param name="credentialResponse"></param> /// <returns>credential response</returns> private static CredentialResponse GetAuthenticationCredentialsResponseToCredentialResponse(GetAuthenticationCredentialsResponse credentialResponse) { CredentialResponse taskResponse; if (credentialResponse.IsValid()) { ICredentials result = new AuthTypeFilteredCredentials( new NetworkCredential(credentialResponse.Username, credentialResponse.Password), credentialResponse.AuthenticationTypes ?? Enumerable.Empty <string>()); taskResponse = new CredentialResponse(result); } else { taskResponse = new CredentialResponse(CredentialStatus.ProviderNotApplicable); } return(taskResponse); }
/// <summary> /// Convert from Plugin CredentialResponse to the CredentialResponse model used by the ICredentialService /// </summary> /// <param name="credentialResponse"></param> /// <returns>credential response</returns> private static CredentialResponse GetAuthenticationCredentialsResponseToCredentialResponse(GetAuthenticationCredentialsResponse credentialResponse) { CredentialResponse taskResponse; if (credentialResponse.IsValid()) { ICredentials result = new NetworkCredential(credentialResponse.Username, credentialResponse.Password); if (credentialResponse.AuthenticationTypes != null) { result = new AuthTypeFilteredCredentials(result, credentialResponse.AuthenticationTypes); } taskResponse = new CredentialResponse(result); } else { taskResponse = new CredentialResponse(CredentialStatus.ProviderNotApplicable); } return(taskResponse); }
/// <param name="uri">The uri of a web resource for which credentials are needed.</param> /// <param name="proxy">Ignored. Proxy information will not be passed to plugins.</param> /// <param name="type"> /// The type of credential request that is being made. Note that this implementation of /// <see cref="ICredentialProvider"/> does not support providing proxy credenitials and treats /// all other types the same. /// </param> /// <param name="isRetry">If true, credentials were previously supplied by this /// provider for the same uri.</param> /// <param name="message">A message provided by NuGet to show to the user when prompting.</param> /// <param name="nonInteractive">If true, the plugin must not prompt for credentials.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <returns>A credential object.</returns> public async Task <CredentialResponse> GetAsync(Uri uri, IWebProxy proxy, CredentialRequestType type, string message, bool isRetry, bool nonInteractive, CancellationToken cancellationToken) { CredentialResponse taskResponse = null; if (type == CredentialRequestType.Proxy || !_isAnAuthenticationPlugin) { taskResponse = new CredentialResponse(CredentialStatus.ProviderNotApplicable); return(taskResponse); } var plugin = await _pluginManager.CreateSourceAgnosticPluginAsync(_discoveredPlugin, cancellationToken); _isAnAuthenticationPlugin = plugin.Claims.Contains(OperationClaim.Authentication); if (_isAnAuthenticationPlugin) { AddOrUpdateLogger(plugin.Plugin); if (proxy != null) { await SetProxyCredentialsToPlugin(uri, proxy, plugin, cancellationToken); } var request = new GetAuthenticationCredentialsRequest(uri, isRetry, nonInteractive); var credentialResponse = await plugin.Plugin.Connection.SendRequestAndReceiveResponseAsync <GetAuthenticationCredentialsRequest, GetAuthenticationCredentialsResponse>( MessageMethod.GetAuthenticationCredentials, request, cancellationToken); taskResponse = GetAuthenticationCredentialsResponseToCredentialResponse(credentialResponse); } else { taskResponse = new CredentialResponse(CredentialStatus.ProviderNotApplicable); } return(taskResponse); }
void AddToCredentialCache(Uri uri, CredentialRequestType type, ICredentialProvider provider, CredentialResponse credentials) { _providerCredentialCache [CredentialCacheKey(uri, type, provider)] = credentials; }
/// <summary> /// Call the plugin credential provider application to acquire credentials. /// The request will be passed to the plugin on standard input as a json serialized /// PluginCredentialRequest. /// The plugin will return credentials as a json serialized PluginCredentialResponse. /// Valid credentials will be returned, or null if the provide cannot provide credentials /// for the given request. If the plugin returns an Abort message, an exception will be thrown to /// fail the current request. /// </summary> /// <param name="uri">The uri of a web resource for which credentials are needed.</param> /// <param name="proxy">Ignored. Proxy information will not be passed to plugins.</param> /// <param name="type"> /// The type of credential request that is being made. Note that this implementation of /// <see cref="ICredentialProvider"/> does not support providing proxy credenitials and treats /// all other types the same. /// </param> /// <param name="isRetry">If true, credentials were previously supplied by this /// provider for the same uri.</param> /// <param name="message">A message provided by NuGet to show to the user when prompting.</param> /// <param name="nonInteractive">If true, the plugin must not prompt for credentials.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <returns>A credential object.</returns> public Task <CredentialResponse> GetAsync( Uri uri, IWebProxy proxy, CredentialRequestType type, string message, bool isRetry, bool nonInteractive, CancellationToken cancellationToken) { CredentialResponse taskResponse; if (type == CredentialRequestType.Proxy) { taskResponse = new CredentialResponse(CredentialStatus.ProviderNotApplicable); return(Task.FromResult(taskResponse)); } try { var request = new PluginCredentialRequest { Uri = uri.AbsoluteUri, IsRetry = isRetry, NonInteractive = nonInteractive, Verbosity = _verbosity }; PluginCredentialResponse response; if (Interlocked.CompareExchange(ref _deprecationMessageWarningLogged, 1, 0) == 0) { _logger.LogWarning(string.Format(CultureInfo.CurrentCulture, Resources.PluginWarning_PluginIsBeingDeprecated, Path, CrossPlatformPluginLink)); } try { response = GetPluginResponse(request, cancellationToken); } catch (PluginUnexpectedStatusException) when(PassVerbosityFlag(request)) { // older providers may throw if the verbosity flag is sent, // so retry without it request.Verbosity = null; response = GetPluginResponse(request, cancellationToken); } if (response.IsValid) { var result = new AuthTypeFilteredCredentials( new NetworkCredential(response.Username, response.Password), response.AuthTypes ?? Enumerable.Empty <string>()); taskResponse = new CredentialResponse(result); } else { taskResponse = new CredentialResponse(CredentialStatus.ProviderNotApplicable); } } catch (OperationCanceledException) { throw; } catch (PluginException) { throw; } catch (Exception e) { throw PluginException.Create(Path, e); } return(Task.FromResult(taskResponse)); }
/// <summary> /// Call the plugin credential provider application to acquire credentials. /// The request will be passed to the plugin on standard input as a json serialized /// PluginCredentialRequest. /// The plugin will return credentials as a json serialized PluginCredentialResponse. /// Valid credentials will be returned, or null if the provide cannot provide credentials /// for the given request. If the plugin returns an Abort message, an exception will be thrown to /// fail the current request. /// </summary> /// <param name="uri">The uri of a web resource for which credentials are needed.</param> /// <param name="proxy">Ignored. Proxy information will not be passed to plugins.</param> /// <param name="type"> /// The type of credential request that is being made. Note that this implementation of /// <see cref="ICredentialProvider"/> does not support providing proxy credenitials and treats /// all other types the same. /// </param> /// <param name="isRetry">If true, credentials were previously supplied by this /// provider for the same uri.</param> /// <param name="message">A message provided by NuGet to show to the user when prompting.</param> /// <param name="nonInteractive">If true, the plugin must not prompt for credentials.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <returns>A credential object. If </returns> public Task <CredentialResponse> GetAsync( Uri uri, IWebProxy proxy, CredentialRequestType type, string message, bool isRetry, bool nonInteractive, CancellationToken cancellationToken) { CredentialResponse taskResponse; if (type == CredentialRequestType.Proxy) { taskResponse = new CredentialResponse(CredentialStatus.ProviderNotApplicable); return(Task.FromResult(taskResponse)); } try { var request = new PluginCredentialRequest { Uri = uri.AbsoluteUri, IsRetry = isRetry, NonInteractive = nonInteractive, Verbosity = _verbosity }; PluginCredentialResponse response; // TODO: Extend the plug protocol to pass in the credential request type. try { response = GetPluginResponse(request, cancellationToken); } catch (PluginUnexpectedStatusException) when(PassVerbosityFlag(request)) { // older providers may throw if the verbosity flag is sent, // so retry without it request.Verbosity = null; response = GetPluginResponse(request, cancellationToken); } if (response.IsValid) { ICredentials result = new NetworkCredential(response.Username, response.Password); if (response.AuthTypes != null) { result = new AuthTypeFilteredCredentials(result, response.AuthTypes); } taskResponse = new CredentialResponse(result); } else { taskResponse = new CredentialResponse(CredentialStatus.ProviderNotApplicable); } } catch (OperationCanceledException) { throw; } catch (PluginException) { throw; } catch (Exception e) { throw PluginException.Create(Path, e); } return(Task.FromResult(taskResponse)); }