Skip to content

Commit

Permalink
Use CredentialCache which limits a credential to a particular authent…
Browse files Browse the repository at this point in the history
…ication mechanism
  • Loading branch information
mconnew committed Mar 22, 2018
1 parent ae80290 commit 13c9efb
Showing 1 changed file with 38 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,12 @@ internal class HttpChannelFactory<TChannel>
private bool _allowCookies;
private AuthenticationSchemes _authenticationScheme;
private HttpCookieContainerManager _httpCookieContainerManager;

// Double-checked locking pattern requires volatile for read/write synchronization
private volatile MruCache<Uri, Uri> _credentialCacheUriPrefixCache;
private volatile MruCache<string, string> _credentialHashCache;
private volatile MruCache<string, HttpClient> _httpClientCache;

private int _maxBufferSize;
private IWebProxy _proxy;
private WebProxyFactory _proxyFactory;
Expand Down Expand Up @@ -255,7 +259,34 @@ private HttpCookieContainerManager GetHttpCookieContainerManager()
return _httpCookieContainerManager;
}

internal async Task<HttpClient> GetHttpClientAsync(EndpointAddress to,
private Uri GetCredentialCacheUriPrefix(Uri via)
{
Uri result;

if (_credentialCacheUriPrefixCache == null)
{
lock (ThisLock)
{
if (_credentialCacheUriPrefixCache == null)
{
_credentialCacheUriPrefixCache = new MruCache<Uri, Uri>(10);
}
}
}

lock (_credentialCacheUriPrefixCache)
{
if (!_credentialCacheUriPrefixCache.TryGetValue(via, out result))
{
result = new UriBuilder(via.Scheme, via.Host, via.Port).Uri;
_credentialCacheUriPrefixCache.Add(via, result);
}
}

return result;
}

internal async Task<HttpClient> GetHttpClientAsync(EndpointAddress to, Uri via,
SecurityTokenProviderContainer tokenProvider, SecurityTokenProviderContainer proxyTokenProvider,
SecurityTokenContainer clientCertificateToken, CancellationToken cancellationToken)
{
Expand Down Expand Up @@ -324,13 +355,16 @@ internal async Task<HttpClient> GetHttpClientAsync(EndpointAddress to,
clientHandler.PreAuthenticate = true;

clientHandler.UseDefaultCredentials = false;
if (credential == CredentialCache.DefaultCredentials)
if (credential == CredentialCache.DefaultCredentials || credential == null)
{
clientHandler.UseDefaultCredentials = true;
}
else
{
clientHandler.Credentials = credential;
CredentialCache credentials = new CredentialCache();
credentials.Add(GetCredentialCacheUriPrefix(via),
AuthenticationSchemesHelper.ToString(_authenticationScheme), credential);
clientHandler.Credentials = credentials;
}

HttpMessageHandler handler = clientHandler;
Expand Down Expand Up @@ -914,7 +948,7 @@ protected async Task<HttpClient> GetHttpClientAsync(EndpointAddress to, Uri via,

try
{
return await Factory.GetHttpClientAsync(to, requestTokenProvider, requestProxyTokenProvider, clientCertificateToken, await timeoutHelper.GetCancellationTokenAsync());
return await Factory.GetHttpClientAsync(to, via, requestTokenProvider, requestProxyTokenProvider, clientCertificateToken, await timeoutHelper.GetCancellationTokenAsync());
}
finally
{
Expand Down

0 comments on commit 13c9efb

Please sign in to comment.