// // we need to do this to handle proxies in the correct way before // calling into the AuthenticationManager APIs // private void PrepareState(HttpWebRequest httpWebRequest) { Uri newUri = IsProxyAuth ? httpWebRequest.ServicePoint.InternalAddress : httpWebRequest.GetRemoteResourceUri(); if ((object)ChallengedUri != (object)newUri) { if ((object)ChallengedUri == null || (object)ChallengedUri.Scheme != (object)newUri.Scheme || ChallengedUri.Host != newUri.Host || ChallengedUri.Port != newUri.Port) { // // must be a new server/port/scheme for this auth state, can happen on a redirect // ChallengedSpn = null; } ChallengedUri = newUri; } httpWebRequest.CurrentAuthenticationState = this; }
// // .Ctors // // // Use only for client HTTP authentication // internal NTAuthentication(string package, NetworkCredential networkCredential, SpnToken spnToken, WebRequest request, ChannelBinding channelBinding) : this(false, package, networkCredential, spnToken.Spn, GetHttpContextFlags(request, spnToken.IsTrusted), request.GetWritingContext(), channelBinding) { // // In order to prevent a race condition where one request could // steal a connection from another request, before a handshake is // complete, we create a new Group for each authentication request. // if (package == NtlmClient.AuthType || package == NegotiateClient.AuthType) { m_UniqueUserId = (Interlocked.Increment(ref s_UniqueGroupId)).ToString(NumberFormatInfo.InvariantInfo) + m_UniqueUserId; } }
// // // internal SpnToken GetComputeSpn(HttpWebRequest httpWebRequest) { if (ChallengedSpn != null) return ChallengedSpn; bool trustNewHost = true; // Assume trusted unless proven otherwise string spnKey = httpWebRequest.ChallengedUri.GetParts(UriComponents.Scheme | UriComponents.Host | UriComponents.Port | UriComponents.Path, UriFormat.SafeUnescaped); SpnToken spnToken = AuthenticationManager.SpnDictionary.InternalGet(spnKey); if (spnToken == null || spnToken.Spn == null) { string host; if (!IsProxyAuth && (httpWebRequest.ServicePoint.InternalProxyServicePoint || httpWebRequest.UseCustomHost)) { // Here the NT-Security folks need us to attempt a DNS lookup to figure out // the FQDN. only do the lookup for short names (no IP addresses or DNS names) // // Initialize a backup value host = httpWebRequest.ChallengedUri.Host; // This host comes from the request/user, assume Trusted unless proven otherwise. if (httpWebRequest.ChallengedUri.HostNameType != UriHostNameType.IPv6 && httpWebRequest.ChallengedUri.HostNameType != UriHostNameType.IPv4 && host.IndexOf('.') == -1) { try { // IPHostEntry result; if (Dns.TryInternalResolve(host, out result)) { host = result.HostName; trustNewHost &= result.isTrustedHost; // Can only lose trust } } catch (Exception exception) { if (NclUtilities.IsFatal(exception)) throw; GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::GetComputeSpn() GetHostByName(host) failed:" + ValidationHelper.ToString(exception)); } } } else { // For this cases we already did a DNS lookup // host = httpWebRequest.ServicePoint.Hostname; trustNewHost &= httpWebRequest.ServicePoint.IsTrustedHost; // Can only lose trust } string spn = "HTTP/" + host; spnKey = httpWebRequest.ChallengedUri.GetParts(UriComponents.SchemeAndServer, UriFormat.SafeUnescaped) + "/"; spnToken = new SpnToken(spn, trustNewHost); AuthenticationManager.SpnDictionary.InternalSet(spnKey, spnToken); } ChallengedSpn = spnToken; return ChallengedSpn; }
internal void InternalSet(string canonicalKey, SpnToken spnToken) { _syncTable[canonicalKey] = spnToken; }