| File: HttpSource\HttpSourceCredentials.cs | Web Access |
| Project: src\nuget-client\src\NuGet.Core\NuGet.Protocol\NuGet.Protocol.csproj (NuGet.Protocol) |
// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Net; namespace NuGet.Protocol { /// <summary> /// A mutable CredentialCache wrapper. This allows the underlying ICredentials to /// be changed to work around HttpClientHandler not allowing Credentials to change. /// This class intentionally inherits from CredentialCache to support authentication on redirects. /// According to System.Net implementation any other ICredentials implementation is dropped for security reasons. /// </summary> public class HttpSourceCredentials : CredentialCache, ICredentials { public HttpSourceCredentials() : this(credentials: null) { } /// <summary> /// Credentials can be changed by other threads, for this reason volatile /// is added below so that the value is not cached anywhere. /// </summary> private volatile VersionedCredentials _credentials = new VersionedCredentials(credentials: null); /// <summary> /// The latest credentials to be used. /// </summary> public ICredentials? Credentials { get { return _credentials.Credentials; } set { // We must update the credentials and it's associated version GUID atomically. This // can be achieved with a reference assignment. It is important that credentials and // version always match. In other words, if the credentials are updated, it should // at no instant be possible to get old version GUID and the new credentials. _credentials = new VersionedCredentials(value); } } /// <summary> /// The latest version ID of the <see cref="Credentials"/>. /// </summary> public Guid Version { get { return _credentials.Version; } } /// <summary> /// Initializes a new instance of the <see cref="HttpSourceCredentials"/> class /// </summary> /// <param name="credentials"> /// Optional initial credentials. May be null. /// </param> public HttpSourceCredentials(ICredentials? credentials = null) { Credentials = credentials; } /// <summary> /// Used by the HttpClientHandler to retrieve the current credentials. /// </summary> NetworkCredential? ICredentials.GetCredential(Uri uri, string authType) { // Get credentials from the current credential store, if any return Credentials?.GetCredential(uri, authType); } private class VersionedCredentials { public VersionedCredentials(ICredentials? credentials) { Version = Guid.NewGuid(); Credentials = credentials; } public ICredentials? Credentials { get; } public Guid Version { get; } } } }