public Authorization Authenticate(string challenge, NetworkCredential credential, object sessionCookie, string spn, ChannelBinding channelBindingToken) { Authorization authorization; if (Logging.On) { Logging.Enter(Logging.Web, this, "Authenticate", (string) null); } try { lock (this.sessions) { NTAuthentication clientContext = this.sessions[sessionCookie] as NTAuthentication; if (clientContext == null) { if (credential == null) { return null; } this.sessions[sessionCookie] = clientContext = new NTAuthentication(false, "Negotiate", credential, spn, ContextFlags.AcceptStream | ContextFlags.Connection, channelBindingToken); } string token = null; if (!clientContext.IsCompleted) { SecurityStatus status; byte[] incomingBlob = null; if (challenge != null) { incomingBlob = Convert.FromBase64String(challenge); } byte[] inArray = clientContext.GetOutgoingBlob(incomingBlob, false, out status); if (clientContext.IsCompleted && (inArray == null)) { token = "\r\n"; } if (inArray != null) { token = Convert.ToBase64String(inArray); } } else { token = this.GetSecurityLayerOutgoingBlob(challenge, clientContext); } authorization = new Authorization(token, clientContext.IsCompleted); } } finally { if (Logging.On) { Logging.Exit(Logging.Web, this, "Authenticate", (string) null); } } return authorization; }
protected override void OnCreateDependencies() { // create a user var userResponse = Client.Post("/user", new { login = "******", password = NewUserPassword, role = 1, status = 0 }, auth: Admin); Assert.That(userResponse.Status, Is.EqualTo(ExpectedCreatedStatus)); var userId = (int)userResponse.Json["id"]; User = new Authorization("User", "_ut", NewUserPassword, userId); RegisterForDeletion("/user/" + userId); // create a client var clientResponse = Client.Post("/oauth/client", new { name = "_ut", oauthId = "_ut_", domain = "_ut.com", redirectUri = "_ut.com", subnet = "127.0.0.0/24" }, auth: Admin); Assert.That(clientResponse.Status, Is.EqualTo(ExpectedCreatedStatus)); ClientID = (int)clientResponse.Json["id"]; ClientSecret = (string)clientResponse.Json["oauthSecret"]; RegisterForDeletion("/oauth/client/" + ClientID); }
internal static void BindModule(Uri uri, Authorization response, IAuthenticationModule module) { if (response.ProtectionRealm != null) { string[] protectionRealm = response.ProtectionRealm; for (int i = 0; i < protectionRealm.Length; i++) { s_ModuleBinding.Add(protectionRealm[i], module.AuthenticationType); } } else { string prefix = generalize(uri); s_ModuleBinding.Add(prefix, module.AuthenticationType); } }
public Authorization Authenticate(string challenge, NetworkCredential credential, object sessionCookie, string spn, ChannelBinding channelBindingToken) { Authorization authorization; if (Logging.On) { Logging.Enter(Logging.Web, this, "Authenticate", (string) null); } try { lock (this.sessions) { NetworkCredential credential2 = this.sessions[sessionCookie] as NetworkCredential; if (credential2 == null) { if ((credential == null) || (credential is SystemNetworkCredential)) { return null; } this.sessions[sessionCookie] = credential; string userName = credential.UserName; string domain = credential.Domain; if ((domain != null) && (domain.Length > 0)) { userName = domain + @"\" + userName; } return new Authorization(Convert.ToBase64String(Encoding.UTF8.GetBytes(userName)), false); } this.sessions.Remove(sessionCookie); authorization = new Authorization(Convert.ToBase64String(Encoding.UTF8.GetBytes(credential2.Password)), true); } } finally { if (Logging.On) { Logging.Exit(Logging.Web, this, "Authenticate", (string) null); } } return authorization; }
// // CONSIDER V.NEXT // creating a static hashtable for server nonces and keep track of nonce count // internal static Authorization Authenticate(HttpDigestChallenge digestChallenge, NetworkCredential NC, string spn, ChannelBinding binding) { string username = NC.InternalGetUserName(); if (ValidationHelper.IsBlankString(username)) { return null; } string password = NC.InternalGetPassword(); bool upgraded = IsUpgraded(digestChallenge.Nonce, binding); if (upgraded) { digestChallenge.ServiceName = spn; digestChallenge.ChannelBinding = hashChannelBinding(binding, digestChallenge.MD5provider); } if (digestChallenge.QopPresent) { if (digestChallenge.ClientNonce==null || digestChallenge.Stale) { GlobalLog.Print("HttpDigest::Authenticate() QopPresent:True, need new nonce. digestChallenge.ClientNonce:" + ValidationHelper.ToString(digestChallenge.ClientNonce) + " digestChallenge.Stale:" + digestChallenge.Stale.ToString()); if (upgraded) { digestChallenge.ClientNonce = createUpgradedNonce(digestChallenge); } else { digestChallenge.ClientNonce = createNonce(32); } digestChallenge.NonceCount = 1; } else { GlobalLog.Print("HttpDigest::Authenticate() QopPresent:True, reusing nonce. digestChallenge.NonceCount:" + digestChallenge.NonceCount.ToString()); digestChallenge.NonceCount++; } } StringBuilder authorization = new StringBuilder(); // // look at username & password, if it's not ASCII we need to attempt some // kind of encoding because we need to calculate the hash on byte[] // Charset usernameCharset = DetectCharset(username); if (!digestChallenge.UTF8Charset && usernameCharset==Charset.UTF8) { GlobalLog.Print("HttpDigest::Authenticate() can't authenticate with UNICODE username. failing auth."); return null; } Charset passwordCharset = DetectCharset(password); if (!digestChallenge.UTF8Charset && passwordCharset==Charset.UTF8) { GlobalLog.Print("HttpDigest::Authenticate() can't authenticate with UNICODE password. failing auth."); return null; } if (digestChallenge.UTF8Charset) { // on the wire always use UTF8 when the server supports it authorization.Append(pair(DA_charset, "utf-8", false)); authorization.Append(","); if (usernameCharset==Charset.UTF8) { username = CharsetEncode(username, Charset.UTF8); authorization.Append(pair(DA_username, username, true)); authorization.Append(","); } else { authorization.Append(pair(DA_username, CharsetEncode(username, Charset.UTF8), true)); authorization.Append(","); username = CharsetEncode(username, usernameCharset); } } else { // otherwise UTF8 is not required username = CharsetEncode(username, usernameCharset); authorization.Append(pair(DA_username, username, true)); authorization.Append(","); } password = CharsetEncode(password, passwordCharset); // no special encoding for the realm since we're just going to echo it back (encoding must have happened on the server). authorization.Append(pair(DA_realm, digestChallenge.Realm, true)); authorization.Append(","); authorization.Append(pair(DA_nonce, digestChallenge.Nonce, true)); authorization.Append(","); authorization.Append(pair(DA_uri, digestChallenge.Uri, true)); if (digestChallenge.QopPresent) { if (digestChallenge.Algorithm!=null) { // consider: should we default to "MD5" here? IE does authorization.Append(","); authorization.Append(pair(DA_algorithm, digestChallenge.Algorithm, true)); // IE sends quotes - IIS needs them } authorization.Append(","); authorization.Append(pair(DA_cnonce, digestChallenge.ClientNonce, true)); authorization.Append(","); authorization.Append(pair(DA_nc, digestChallenge.NonceCount.ToString("x8", NumberFormatInfo.InvariantInfo), false)); // RAID#47397 // send only the QualityOfProtection we're using // since we support only "auth" that's what we will send out authorization.Append(","); authorization.Append(pair(DA_qop, SupportedQuality, true)); // IE sends quotes - IIS needs them if (upgraded) { authorization.Append(","); authorization.Append(pair(DA_hasheddirs, HashedDirs, true)); authorization.Append(","); authorization.Append(pair(DA_servicename, digestChallenge.ServiceName, true)); authorization.Append(","); authorization.Append(pair(DA_channelbinding, digestChallenge.ChannelBinding, true)); } } // warning: this must be computed here string responseValue = HttpDigest.responseValue(digestChallenge, username, password); if (responseValue==null) { return null; } authorization.Append(","); authorization.Append(pair(DA_response, responseValue, true)); // IE sends quotes - IIS needs them if (digestChallenge.Opaque!=null) { authorization.Append(","); authorization.Append(pair(DA_opaque, digestChallenge.Opaque, true)); } GlobalLog.Print("HttpDigest::Authenticate() digestChallenge.Stale:" + digestChallenge.Stale.ToString()); // completion is decided in Update() Authorization finalAuthorization = new Authorization(DigestClient.AuthType + " " + authorization.ToString(), false); return finalAuthorization; }
// On Windows XP and up, WDigest.dll supports the Digest authentication scheme (in addition to // support for HTTP client sides, it also supports HTTP server side and SASL) through SSPI. private Authorization XPDoAuthenticate(string challenge, HttpWebRequest httpWebRequest, ICredentials credentials, bool preAuthenticate) { GlobalLog.Print("DigestClient::XPDoAuthenticate() challenge:[" + ValidationHelper.ToString(challenge) + "] httpWebRequest#" + ValidationHelper.HashString(httpWebRequest) + " credentials#" + ValidationHelper.HashString(credentials) + " preAuthenticate:" + preAuthenticate.ToString()); NTAuthentication authSession = null; string incoming = null; int index; if (!preAuthenticate) { index = AuthenticationManager.FindSubstringNotInQuotes(challenge, Signature); if (index < 0) { return null; } authSession = httpWebRequest.CurrentAuthenticationState.GetSecurityContext(this); GlobalLog.Print("DigestClient::XPDoAuthenticate() key:" + ValidationHelper.HashString(httpWebRequest.CurrentAuthenticationState) + " retrieved authSession:" + ValidationHelper.HashString(authSession)); incoming = RefineDigestChallenge(challenge, index); } else { #if WDIGEST_PREAUTH GlobalLog.Print("DigestClient::XPDoAuthenticate() looking up digestChallenge for prefix:" + httpWebRequest.ChallengedUri.AbsoluteUri); authSession = challengeCache.Lookup(httpWebRequest.ChallengedUri.AbsoluteUri) as NTAuthentication; if (authSession==null) { return null; } #else GlobalLog.Print("DigestClient::XPDoAuthenticate() looking up digestChallenge for prefix:" + httpWebRequest.ChallengedUri.AbsoluteUri); HttpDigestChallenge digestChallenge = challengeCache.Lookup(httpWebRequest.ChallengedUri.AbsoluteUri) as HttpDigestChallenge; if (digestChallenge==null) { return null; } GlobalLog.Print("DigestClient::XPDoAuthenticate() retrieved digestChallenge#" + ValidationHelper.HashString(digestChallenge) + " digestChallenge for prefix:" + httpWebRequest.ChallengedUri.AbsoluteUri); digestChallenge = digestChallenge.CopyAndIncrementNonce(); digestChallenge.SetFromRequest(httpWebRequest); incoming = digestChallenge.ToBlob(); #endif } UriComponents uriParts = 0; Uri remoteUri = httpWebRequest.GetRemoteResourceUri(); if (httpWebRequest.CurrentMethod.ConnectRequest) { uriParts = UriComponents.HostAndPort; // Use the orriginal request Uri, not the proxy Uri remoteUri = httpWebRequest.RequestUri; } else { uriParts = UriComponents.PathAndQuery; } // here we use Address instead of ChallengedUri. This is because the // Digest hash is generated using the uri as it is present on the wire string rawUri = remoteUri.GetParts(uriParts, UriFormat.UriEscaped); GlobalLog.Print("DigestClient::XPDoAuthenticate() rawUri:" + ValidationHelper.ToString(rawUri)); if (authSession==null) { NetworkCredential NC = credentials.GetCredential(httpWebRequest.ChallengedUri, Signature); GlobalLog.Print("DigestClient::XPDoAuthenticate() GetCredential() returns:" + ValidationHelper.ToString(NC)); if (NC == null || (!(NC is SystemNetworkCredential) && NC.InternalGetUserName().Length == 0)) { return null; } ICredentialPolicy policy = AuthenticationManager.CredentialPolicy; if (policy != null && !policy.ShouldSendCredential(httpWebRequest.ChallengedUri, httpWebRequest, NC, this)) return null; SpnToken spn = httpWebRequest.CurrentAuthenticationState.GetComputeSpn(httpWebRequest); GlobalLog.Print("NtlmClient::Authenticate() ChallengedSpn:" + ValidationHelper.ToString(spn)); ChannelBinding binding = null; if (httpWebRequest.CurrentAuthenticationState.TransportContext != null) { binding = httpWebRequest.CurrentAuthenticationState.TransportContext.GetChannelBinding(ChannelBindingKind.Endpoint); } authSession = new NTAuthentication( NegotiationInfoClass.WDigest, NC, spn, httpWebRequest, binding); GlobalLog.Print("DigestClient::XPDoAuthenticate() setting SecurityContext for:" + ValidationHelper.HashString(httpWebRequest.CurrentAuthenticationState) + " to authSession:" + ValidationHelper.HashString(authSession)); httpWebRequest.CurrentAuthenticationState.SetSecurityContext(authSession, this); } SecurityStatus statusCode; string clientResponse; GlobalLog.Print("DigestClient::XPDoAuthenticate() incoming:" + ValidationHelper.ToString(incoming)); #if WDIGEST_PREAUTH clientResponse = authSession.GetOutgoingDigestBlob(incoming, httpWebRequest.CurrentMethod.Name, rawUri, null, preAuthenticate, true, out statusCode); #else clientResponse = authSession.GetOutgoingDigestBlob(incoming, httpWebRequest.CurrentMethod.Name, rawUri, null, false, false, out statusCode); #endif if (clientResponse == null) return null; GlobalLog.Print("DigestClient::XPDoAuthenticate() GetOutgoingDigestBlob(" + incoming + ") returns:" + ValidationHelper.ToString(clientResponse)); Authorization digestResponse = new Authorization(AuthType + " " + clientResponse, authSession.IsCompleted, string.Empty, authSession.IsMutualAuthFlag); if (!preAuthenticate && httpWebRequest.PreAuthenticate) { // add this to the cache of challenges so we can preauthenticate // use this DCR when avaialble to do this without calling HttpDigest.Interpret(): // 762115 3 WDigest should allow an application to retrieve the parsed domain directive HttpDigestChallenge digestChallenge = HttpDigest.Interpret(incoming, -1, httpWebRequest); string[] prefixes = digestChallenge.Domain==null ? new string[]{httpWebRequest.ChallengedUri.GetParts(UriComponents.SchemeAndServer, UriFormat.UriEscaped)} : digestChallenge.Domain.Split(singleSpaceArray); // If Domain property is not set we associate Digest only with the server Uri namespace (used to do with whole server) digestResponse.ProtectionRealm = digestChallenge.Domain==null ? null: prefixes; for (int i=0; i<prefixes.Length; i++) { GlobalLog.Print("DigestClient::XPDoAuthenticate() adding authSession#" + ValidationHelper.HashString(authSession) + " for prefix:" + prefixes[i]); #if WDIGEST_PREAUTH challengeCache.Add(prefixes[i], authSession); #else challengeCache.Add(prefixes[i], digestChallenge); #endif } } return digestResponse; }
internal AuthenticateCallbackContext(SmtpConnection thisPtr, ISmtpAuthenticationModule module, NetworkCredential credential, string spn, ChannelBinding Token) { this.thisPtr = thisPtr; this.module = module; this.credential = credential; this.spn = spn; this.token = Token; this.result = null; }
/// <devdoc> /// <para> /// Binds an authentication response to a request for pre-authentication. /// </para> /// </devdoc> // Create binding between an authorization response and the module // generating that response // This association is used for deciding which module to invoke // for preauthentication purposes public abstract void BindModule(Uri uri, Authorization response, IAuthenticationModule module);
public Authorization Authenticate(string challenge, WebRequest webRequest, ICredentials credentials) { GlobalLog.Print("DigestClient::Authenticate(): " + challenge); #if XP_WDIGEST if (ComNetOS.IsPostWin2K) { return(XPDigestClient.Authenticate(challenge, webRequest, credentials)); } #endif // #if XP_WDIGEST GlobalLog.Assert(credentials != null, "DigestClient::Authenticate() credentials==null", ""); if (credentials == null || credentials is SystemNetworkCredential) { return(null); } HttpWebRequest httpWebRequest = webRequest as HttpWebRequest; GlobalLog.Assert(httpWebRequest != null, "DigestClient::Authenticate() httpWebRequest==null", ""); if (httpWebRequest == null || httpWebRequest.ChallengedUri == null) { // // there has been no challenge: // 1) the request never went on the wire // 2) somebody other than us is calling into AuthenticationManager // return(null); } int index = AuthenticationManager.FindSubstringNotInQuotes(challenge.ToLower(CultureInfo.InvariantCulture), Signature); if (index < 0) { return(null); } string[] prefixes = null; string rootPath = httpWebRequest.ChallengedUri.Scheme + "://" + httpWebRequest.ChallengedUri.Host; HttpDigestChallenge digestChallenge = HttpDigest.Interpret(challenge, index, httpWebRequest); if (digestChallenge == null) { return(null); } if (digestChallenge.Domain == null) { challengeCache.Add(rootPath, digestChallenge); } else { prefixes = digestChallenge.Domain.Split(" ".ToCharArray()); for (int i = 0; i < prefixes.Length; i++) { challengeCache.Add(prefixes[i], digestChallenge); } } Authorization digestResponse = HttpDigest.Authenticate(digestChallenge, credentials); if (digestResponse != null) { if (prefixes == null) { digestResponse.ProtectionRealm = new string[1]; digestResponse.ProtectionRealm[0] = rootPath; } else { digestResponse.ProtectionRealm = prefixes; } } return(digestResponse); }
private Authorization XPDoAuthenticate(string challenge, HttpWebRequest httpWebRequest, ICredentials credentials, bool preAuthenticate) { NTAuthentication securityContext = null; string incomingBlob = null; SecurityStatus status; if (!preAuthenticate) { int index = AuthenticationManager.FindSubstringNotInQuotes(challenge, Signature); if (index < 0) { return null; } securityContext = httpWebRequest.CurrentAuthenticationState.GetSecurityContext(this); incomingBlob = RefineDigestChallenge(challenge, index); } else { HttpDigestChallenge challenge2 = challengeCache.Lookup(httpWebRequest.ChallengedUri.AbsoluteUri) as HttpDigestChallenge; if (challenge2 == null) { return null; } challenge2 = challenge2.CopyAndIncrementNonce(); challenge2.SetFromRequest(httpWebRequest); incomingBlob = challenge2.ToBlob(); } UriComponents uriParts = 0; if (httpWebRequest.CurrentMethod.ConnectRequest) { uriParts = UriComponents.HostAndPort; } else if (httpWebRequest.UsesProxySemantics) { uriParts = UriComponents.HttpRequestUrl; } else { uriParts = UriComponents.PathAndQuery; } string parts = httpWebRequest.GetRemoteResourceUri().GetParts(uriParts, UriFormat.UriEscaped); if (securityContext == null) { NetworkCredential credential = credentials.GetCredential(httpWebRequest.ChallengedUri, Signature); if ((credential == null) || (!(credential is SystemNetworkCredential) && (credential.InternalGetUserName().Length == 0))) { return null; } ICredentialPolicy credentialPolicy = AuthenticationManager.CredentialPolicy; if ((credentialPolicy != null) && !credentialPolicy.ShouldSendCredential(httpWebRequest.ChallengedUri, httpWebRequest, credential, this)) { return null; } string computeSpn = httpWebRequest.CurrentAuthenticationState.GetComputeSpn(httpWebRequest); ChannelBinding channelBinding = null; if (httpWebRequest.CurrentAuthenticationState.TransportContext != null) { channelBinding = httpWebRequest.CurrentAuthenticationState.TransportContext.GetChannelBinding(ChannelBindingKind.Endpoint); } securityContext = new NTAuthentication("WDigest", credential, computeSpn, httpWebRequest, channelBinding); httpWebRequest.CurrentAuthenticationState.SetSecurityContext(securityContext, this); } string str4 = securityContext.GetOutgoingDigestBlob(incomingBlob, httpWebRequest.CurrentMethod.Name, parts, null, false, false, out status); if (str4 == null) { return null; } Authorization authorization = new Authorization("Digest " + str4, securityContext.IsCompleted, string.Empty, securityContext.IsMutualAuthFlag); if (!preAuthenticate && httpWebRequest.PreAuthenticate) { HttpDigestChallenge challenge3 = HttpDigest.Interpret(incomingBlob, -1, httpWebRequest); string[] strArray = (challenge3.Domain == null) ? new string[] { httpWebRequest.ChallengedUri.GetParts(UriComponents.SchemeAndServer, UriFormat.UriEscaped) } : challenge3.Domain.Split(singleSpaceArray); authorization.ProtectionRealm = (challenge3.Domain == null) ? null : strArray; for (int i = 0; i < strArray.Length; i++) { challengeCache.Add(strArray[i], challenge3); } } return authorization; }
// Create binding between an authorization response and the module // generating that response // This association is used for deciding which module to invoke // for preauthentication purposes private static void createModuleBinding(WebRequest request, Authorization response, IAuthenticationModule module) { if (!module.CanPreAuthenticate) { return; } if (response.ProtectionRealm!=null) { // The authentication module specified which Uri prefixes // will be preauthenticated string[] prefix = response.ProtectionRealm; for (int k=0; k<prefix.Length; k++) { // // PrefixLookup is thread-safe // s_ModuleBinding.Add(prefix[k], module.AuthenticationType); } } else { // Otherwise use the default policy for "fabricating" // some protection realm generalizing the particular Uri // Consider: should this be ChallengedUri? string prefix = generalize(request.RequestUri); // // PrefixLookup is thread-safe // s_ModuleBinding.Add(prefix, module.AuthenticationType); } return; }
/// <devdoc> /// <para> /// Binds an authentication response to a request for pre-authentication. /// </para> /// </devdoc> // Create binding between an authorization response and the module // generating that response // This association is used for deciding which module to invoke // for preauthentication purposes internal static void BindModule(Uri uri, Authorization response, IAuthenticationModule module) { Instance.BindModule(uri, response, module); }
bool CreateTunnel(HttpWebRequest request, Stream stream, out byte [] buffer) { StringBuilder sb = new StringBuilder(); sb.Append("CONNECT "); sb.Append(request.Address.Host); sb.Append(':'); sb.Append(request.Address.Port); sb.Append(" HTTP/"); if (request.ServicePoint.ProtocolVersion == HttpVersion.Version11) { sb.Append("1.1"); } else { sb.Append("1.0"); } sb.Append("\r\nHost: "); sb.Append(request.Address.Authority); string challenge = Data.Challenge; Data.Challenge = null; bool have_auth = (request.Headers ["Proxy-Authorization"] != null); if (have_auth) { sb.Append("\r\nProxy-Authorization: "); sb.Append(request.Headers ["Proxy-Authorization"]); } else if (challenge != null && Data.StatusCode == 407) { have_auth = true; ICredentials creds = request.Proxy.Credentials; Authorization auth = AuthenticationManager.Authenticate(challenge, request, creds); if (auth != null) { sb.Append("\r\nProxy-Authorization: "); sb.Append(auth.Message); } } sb.Append("\r\n\r\n"); Data.StatusCode = 0; byte [] connectBytes = Encoding.Default.GetBytes(sb.ToString()); stream.Write(connectBytes, 0, connectBytes.Length); int status; WebHeaderCollection result = ReadHeaders(request, stream, out buffer, out status); if (!have_auth && result != null && status == 407) // Needs proxy auth { Data.StatusCode = status; Data.Challenge = result ["Proxy-Authenticate"]; return(false); } else if (status != 200) { string msg = String.Format("The remote server returned a {0} status code.", status); HandleError(WebExceptionStatus.SecureChannelFailure, null, msg); return(false); } return(result != null); }
private Authorization DoAuthenticate(string challenge, WebRequest webRequest, ICredentials credentials, bool preAuthenticate) { HttpDigestChallenge challenge2; if (credentials == null) { return(null); } HttpWebRequest httpWebRequest = webRequest as HttpWebRequest; NetworkCredential credential = credentials.GetCredential(httpWebRequest.ChallengedUri, Signature); if (credential is SystemNetworkCredential) { if (WDigestAvailable) { return(this.XPDoAuthenticate(challenge, httpWebRequest, credentials, preAuthenticate)); } return(null); } if (!preAuthenticate) { int startingPoint = AuthenticationManager.FindSubstringNotInQuotes(challenge, Signature); if (startingPoint < 0) { return(null); } challenge2 = HttpDigest.Interpret(challenge, startingPoint, httpWebRequest); } else { challenge2 = challengeCache.Lookup(httpWebRequest.ChallengedUri.AbsoluteUri) as HttpDigestChallenge; } if (challenge2 == null) { return(null); } if (!CheckQOP(challenge2)) { if (Logging.On) { Logging.PrintError(Logging.Web, SR.GetString("net_log_digest_qop_not_supported", new object[] { challenge2.QualityOfProtection })); } return(null); } if (preAuthenticate) { challenge2 = challenge2.CopyAndIncrementNonce(); challenge2.SetFromRequest(httpWebRequest); } if (credential == null) { return(null); } ICredentialPolicy credentialPolicy = AuthenticationManager.CredentialPolicy; if ((credentialPolicy != null) && !credentialPolicy.ShouldSendCredential(httpWebRequest.ChallengedUri, httpWebRequest, credential, this)) { return(null); } string computeSpn = httpWebRequest.CurrentAuthenticationState.GetComputeSpn(httpWebRequest); ChannelBinding channelBinding = null; if (httpWebRequest.CurrentAuthenticationState.TransportContext != null) { channelBinding = httpWebRequest.CurrentAuthenticationState.TransportContext.GetChannelBinding(ChannelBindingKind.Endpoint); } Authorization authorization = HttpDigest.Authenticate(challenge2, credential, computeSpn, channelBinding); if ((!preAuthenticate && webRequest.PreAuthenticate) && (authorization != null)) { string[] strArray = (challenge2.Domain == null) ? new string[] { httpWebRequest.ChallengedUri.GetParts(UriComponents.SchemeAndServer, UriFormat.UriEscaped) } : challenge2.Domain.Split(singleSpaceArray); authorization.ProtectionRealm = (challenge2.Domain == null) ? null : strArray; for (int i = 0; i < strArray.Length; i++) { challengeCache.Add(strArray[i], challenge2); } } return(authorization); }
/// <summary> /// Authenticate the web request. /// </summary> /// <param name="request">Current web request.</param> /// <param name="credentials">OAuthCredentials object.</param> /// <returns>Populated Authorization object.</returns> static Authorization Auth(WebRequest request, ICredentials credentials) { OAuthCredentialsStandard cred = credentials as OAuthCredentialsStandard; if (cred != null) { NameValueCollection postArgs = new NameValueCollection(); string realm = OAuthUtility.Realm(request.RequestUri); string authstr = "OAuth realm=\"" + realm + "\", " + OAuthClient.GetAuthParameters(request.RequestUri, cred.Token, cred.Arguments, cred.Consumer.ConsumerKey, cred.Consumer.ConsumerSecret, cred.RsaCertificate, AuthenticationMethod.Header, request.Method, cred.Consumer.SignatureType); Trace.WriteLine(authstr, "Credentials"); Authorization auth = new Authorization(authstr); return auth; } OAuthCredentialsTwoLegged tcred = credentials as OAuthCredentialsTwoLegged; if (tcred != null) { string realm = OAuthUtility.Realm(request.RequestUri); string authstr = "OAuth realm=\"" + realm + "\", " + OAuthClient.GetAuthParameters(request.RequestUri, tcred.RequestorId, tcred.Arguments, tcred.Consumer.ConsumerKey, tcred.Consumer.ConsumerSecret, tcred.RsaCertificate, AuthenticationMethod.Header, request.Method, tcred.Consumer.SignatureType); Trace.WriteLine(authstr, "Credentials"); Authorization auth = new Authorization(authstr); return auth; } return null; }
public static Authorization Authenticate(string challenge, WebRequest webRequest, ICredentials credentials) { GlobalLog.Print("XPDigestClient::Authenticate(): " + challenge); GlobalLog.Assert(credentials != null, "XPDigestClient::Authenticate() credentials==null", ""); if (credentials == null) { return(null); } HttpWebRequest httpWebRequest = webRequest as HttpWebRequest; GlobalLog.Assert(httpWebRequest != null, "XPDigestClient::Authenticate() httpWebRequest==null", ""); if (httpWebRequest == null || httpWebRequest.ChallengedUri == null) { // // there has been no challenge: // 1) the request never went on the wire // 2) somebody other than us is calling into AuthenticationManager // return(null); } int index = AuthenticationManager.FindSubstringNotInQuotes(challenge.ToLower(CultureInfo.InvariantCulture), DigestClient.Signature); if (index < 0) { return(null); } int blobBegin = index + DigestClient.SignatureSize; string incoming = null; // // there may be multiple challenges. If the next character after the // package name is not a comma then it is challenge data // if (challenge.Length > blobBegin && challenge[blobBegin] != ',') { ++blobBegin; } else { index = -1; } if (index >= 0 && challenge.Length > blobBegin) { incoming = challenge.Substring(blobBegin); } NTAuthentication authSession = sessions[httpWebRequest.CurrentAuthenticationState] as NTAuthentication; GlobalLog.Print("XPDigestClient::Authenticate() key:" + ValidationHelper.HashString(httpWebRequest.CurrentAuthenticationState) + " retrieved authSession:" + ValidationHelper.HashString(authSession)); if (authSession == null) { NetworkCredential NC = credentials.GetCredential(httpWebRequest.ChallengedUri, DigestClient.Signature); GlobalLog.Print("XPDigestClient::Authenticate() GetCredential() returns:" + ValidationHelper.ToString(NC)); if (NC == null) { return(null); } string username = NC.UserName; if (username == null || (username.Length == 0 && !(NC is SystemNetworkCredential))) { return(null); } authSession = new NTAuthentication( "WDigest", NC, httpWebRequest.ChallengedUri.AbsolutePath, httpWebRequest.DelegationFix); GlobalLog.Print("XPDigestClient::Authenticate() adding authSession:" + ValidationHelper.HashString(authSession) + " for:" + ValidationHelper.HashString(httpWebRequest.CurrentAuthenticationState)); sessions.Add(httpWebRequest.CurrentAuthenticationState, authSession); } bool handshakeComplete; string clientResponse = authSession.GetOutgoingDigestBlob(incoming, httpWebRequest.CurrentMethod, out handshakeComplete); GlobalLog.Print("XPDigestClient::Authenticate() GetOutgoingDigestBlob(" + incoming + ") returns:" + ValidationHelper.ToString(clientResponse)); GlobalLog.Assert(handshakeComplete, "XPDigestClient::Authenticate() handshakeComplete==false", ""); if (!handshakeComplete) { return(null); } // completion is decided in Update() Authorization finalAuthorization = new Authorization(DigestClient.AuthType + " " + clientResponse, false); return(finalAuthorization); }
// // CONSIDER V.NEXT // creating a static hashtable for server nonces and keep track of nonce count // public static Authorization Authenticate(HttpDigestChallenge digestChallenge, ICredentials credentials) { NetworkCredential NC = credentials.GetCredential(digestChallenge.ChallengedUri, DigestClient.Signature); GlobalLog.Print("HttpDigest::Authenticate() GetCredential() returns:" + ValidationHelper.ToString(NC)); if (NC == null) { return(null); } string username = NC.UserName; if (ValidationHelper.IsBlankString(username)) { return(null); } string password = NC.Password; if (digestChallenge.QopPresent) { if (digestChallenge.ClientNonce == null || digestChallenge.Stale) { GlobalLog.Print("HttpDigest::Authenticate() QopPresent:True, need new nonce. digestChallenge.ClientNonce:" + ValidationHelper.ToString(digestChallenge.ClientNonce) + " digestChallenge.Stale:" + digestChallenge.Stale.ToString()); digestChallenge.ClientNonce = createNonce(32); digestChallenge.NonceCount = 1; } else { GlobalLog.Print("HttpDigest::Authenticate() QopPresent:True, reusing nonce. digestChallenge.NonceCount:" + digestChallenge.NonceCount.ToString()); digestChallenge.NonceCount++; } } StringBuilder authorization = new StringBuilder(); // // look at username & password, if it's not ASCII we need to attempt some // kind of encoding because we need to calculate the hash on byte[] // Charset usernameCharset = DetectCharset(username); if (!digestChallenge.UTF8Charset && usernameCharset == Charset.UTF8) { GlobalLog.Print("HttpDigest::Authenticate() can't authenticate with UNICODE username. failing auth."); return(null); } Charset passwordCharset = DetectCharset(password); if (!digestChallenge.UTF8Charset && passwordCharset == Charset.UTF8) { GlobalLog.Print("HttpDigest::Authenticate() can't authenticate with UNICODE password. failing auth."); return(null); } if (digestChallenge.UTF8Charset) { // on the wire always use UTF8 when the server supports it authorization.Append(pair(DA_charset, "utf-8", false)); authorization.Append(","); if (usernameCharset == Charset.UTF8) { username = CharsetEncode(username, Charset.UTF8); authorization.Append(pair(DA_username, username, true)); authorization.Append(","); } else { authorization.Append(pair(DA_username, CharsetEncode(username, Charset.UTF8), true)); authorization.Append(","); username = CharsetEncode(username, usernameCharset); } } else { // otherwise UTF8 is not required username = CharsetEncode(username, usernameCharset); authorization.Append(pair(DA_username, username, true)); authorization.Append(","); } password = CharsetEncode(password, passwordCharset); // no special encoding for the realm since we're just going to echo it back (encoding must have happened on the server). authorization.Append(pair(DA_realm, digestChallenge.Realm, true)); authorization.Append(","); authorization.Append(pair(DA_nonce, digestChallenge.Nonce, true)); authorization.Append(","); authorization.Append(pair(DA_uri, digestChallenge.Uri, true)); if (digestChallenge.QopPresent) { // // RAID#47397 // send only the QualityOfProtection we're using // since we support only "auth" that's what we will send out // if (digestChallenge.Algorithm != null) { // // consider: should we default to "MD5" here? IE does // authorization.Append(","); authorization.Append(pair(DA_algorithm, digestChallenge.Algorithm, true)); // IE sends quotes - IIS needs them } authorization.Append(","); authorization.Append(pair(DA_cnonce, digestChallenge.ClientNonce, true)); authorization.Append(","); authorization.Append(pair(DA_nc, digestChallenge.NonceCount.ToString("x8"), false)); authorization.Append(","); authorization.Append(pair(DA_qop, SupportedQuality, true)); // IE sends quotes - IIS needs them } // warning: this must be computed here string responseValue = HttpDigest.responseValue(digestChallenge, username, password); if (responseValue == null) { return(null); } authorization.Append(","); authorization.Append(pair(DA_response, responseValue, true)); // IE sends quotes - IIS needs them if (digestChallenge.Opaque != null) { authorization.Append(","); authorization.Append(pair(DA_opaque, digestChallenge.Opaque, true)); } GlobalLog.Print("HttpDigest::Authenticate() digestChallenge.Stale:" + digestChallenge.Stale.ToString()); // completion is decided in Update() Authorization finalAuthorization = new Authorization(DigestClient.AuthType + " " + authorization.ToString(), false); return(finalAuthorization); }
/// <devdoc> /// <para> /// Binds an authentication response to a request for pre-authentication. /// </para> /// </devdoc> // Create binding between an authorization response and the module // generating that response // This association is used for deciding which module to invoke // for preauthentication purposes public override void BindModule(Uri uri, Authorization response, IAuthenticationModule module) { GlobalLog.Assert( module.CanPreAuthenticate, "AuthenticationManager::BindModule()|module.CanPreAuthenticate == false"); if (response.ProtectionRealm != null) { // The authentication module specified which Uri prefixes // will be preauthenticated string[] prefix = response.ProtectionRealm; for (int k = 0; k < prefix.Length; k++) { // // PrefixLookup is thread-safe // moduleBinding.Add(prefix[k], module.AuthenticationType.ToUpperInvariant()); } } else { // Otherwise use the default policy for "fabricating" // some protection realm generalizing the particular Uri string prefix = generalize(uri); // // PrefixLookup is thread-safe // moduleBinding.Add(prefix, module.AuthenticationType); } }
/// <include file='doc\AuthenticationManager.uex' path='docs/doc[@for="AuthenticationManager.BindModule"]/*' /> /// <devdoc> /// <para> /// Binds an authentication response to a request for pre-authentication. /// </para> /// </devdoc> internal static void BindModule(WebRequest request, Authorization response) { createModuleBinding(request, response, response.Module); }
internal void ClearAuthReq(HttpWebRequest httpWebRequest) { // // if we are authenticating and we're being redirected to // another authentication space then remove the current // authentication header // GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::ClearAuthReq() httpWebRequest#" + ValidationHelper.HashString(httpWebRequest) + " " + AuthorizationHeader.ToString() + ": " + ValidationHelper.ToString(httpWebRequest.Headers[AuthorizationHeader])); TriedPreAuth = false; Authorization = null; UniqueGroupId = null; httpWebRequest.Headers.Remove(AuthorizationHeader); }
private Authorization XPDoAuthenticate(string challenge, HttpWebRequest httpWebRequest, ICredentials credentials, bool preAuthenticate) { NTAuthentication securityContext = null; string incomingBlob = null; SecurityStatus status; if (!preAuthenticate) { int index = AuthenticationManager.FindSubstringNotInQuotes(challenge, Signature); if (index < 0) { return(null); } securityContext = httpWebRequest.CurrentAuthenticationState.GetSecurityContext(this); incomingBlob = RefineDigestChallenge(challenge, index); } else { HttpDigestChallenge challenge2 = challengeCache.Lookup(httpWebRequest.ChallengedUri.AbsoluteUri) as HttpDigestChallenge; if (challenge2 == null) { return(null); } challenge2 = challenge2.CopyAndIncrementNonce(); challenge2.SetFromRequest(httpWebRequest); incomingBlob = challenge2.ToBlob(); } UriComponents uriParts = 0; if (httpWebRequest.CurrentMethod.ConnectRequest) { uriParts = UriComponents.HostAndPort; } else if (httpWebRequest.UsesProxySemantics) { uriParts = UriComponents.HttpRequestUrl; } else { uriParts = UriComponents.PathAndQuery; } string parts = httpWebRequest.GetRemoteResourceUri().GetParts(uriParts, UriFormat.UriEscaped); if (securityContext == null) { NetworkCredential credential = credentials.GetCredential(httpWebRequest.ChallengedUri, Signature); if ((credential == null) || (!(credential is SystemNetworkCredential) && (credential.InternalGetUserName().Length == 0))) { return(null); } ICredentialPolicy credentialPolicy = AuthenticationManager.CredentialPolicy; if ((credentialPolicy != null) && !credentialPolicy.ShouldSendCredential(httpWebRequest.ChallengedUri, httpWebRequest, credential, this)) { return(null); } string computeSpn = httpWebRequest.CurrentAuthenticationState.GetComputeSpn(httpWebRequest); ChannelBinding channelBinding = null; if (httpWebRequest.CurrentAuthenticationState.TransportContext != null) { channelBinding = httpWebRequest.CurrentAuthenticationState.TransportContext.GetChannelBinding(ChannelBindingKind.Endpoint); } securityContext = new NTAuthentication("WDigest", credential, computeSpn, httpWebRequest, channelBinding); httpWebRequest.CurrentAuthenticationState.SetSecurityContext(securityContext, this); } string str4 = securityContext.GetOutgoingDigestBlob(incomingBlob, httpWebRequest.CurrentMethod.Name, parts, null, false, false, out status); if (str4 == null) { return(null); } Authorization authorization = new Authorization("Digest " + str4, securityContext.IsCompleted, string.Empty, securityContext.IsMutualAuthFlag); if (!preAuthenticate && httpWebRequest.PreAuthenticate) { HttpDigestChallenge challenge3 = HttpDigest.Interpret(incomingBlob, -1, httpWebRequest); string[] strArray = (challenge3.Domain == null) ? new string[] { httpWebRequest.ChallengedUri.GetParts(UriComponents.SchemeAndServer, UriFormat.UriEscaped) } : challenge3.Domain.Split(singleSpaceArray); authorization.ProtectionRealm = (challenge3.Domain == null) ? null : strArray; for (int i = 0; i < strArray.Length; i++) { challengeCache.Add(strArray[i], challenge3); } } return(authorization); }
// // attempts to authenticate the request: // returns true only if it succesfully called into the AuthenticationManager // and got back a valid Authorization and succesfully set the appropriate auth headers // internal bool AttemptAuthenticate(HttpWebRequest httpWebRequest, ICredentials authInfo) { // // Check for previous authentication attempts or the presence of credentials // GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() httpWebRequest#" + ValidationHelper.HashString(httpWebRequest) + " AuthorizationHeader:" + AuthorizationHeader.ToString()); if (Authorization!=null && Authorization.Complete) { GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() Authorization!=null Authorization.Complete:" + Authorization.Complete.ToString()); if (IsProxyAuth) { GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() ProxyAuth cleaning up auth status"); ClearAuthReq(httpWebRequest); } return false; } if (authInfo==null) { GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() authInfo==null Authorization#" + ValidationHelper.HashString(Authorization)); return false; } string challenge = httpWebRequest.AuthHeader(AuthenticateHeader); if (challenge==null) { // // the server sent no challenge, but this might be the case // in which we're succeeding an authorization handshake to // a proxy while a handshake with the server is still in progress. // if the handshake with the proxy is complete and we actually have // a handshake with the server in progress we can send the authorization header for the server as well. // if (!IsProxyAuth && Authorization!=null && httpWebRequest.ProxyAuthenticationState.Authorization!=null) { httpWebRequest.Headers.Set(AuthorizationHeader, Authorization.Message); } GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() challenge==null Authorization#" + ValidationHelper.HashString(Authorization)); return false; } // // if the AuthenticationManager throws on Authenticate, // bubble up that Exception to the user // GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() challenge:" + challenge); PrepareState(httpWebRequest); try { Authorization = AuthenticationManager.Authenticate(challenge, httpWebRequest, authInfo); } catch (Exception exception) { Authorization = null; GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::PreAuthIfNeeded() PreAuthenticate() returned exception:" + exception.Message); ClearSession(httpWebRequest); throw; } catch { Authorization = null; GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::PreAuthIfNeeded() PreAuthenticate() returned exception: Non-CLS Compliant Exception"); ClearSession(httpWebRequest); throw; } if (Authorization==null) { GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() Authorization==null"); return false; } if (Authorization.Message==null) { GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() Authorization.Message==null"); Authorization = null; return false; } UniqueGroupId = Authorization.ConnectionGroupId; GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() AuthorizationHeader:" + AuthorizationHeader + " blob: " + Authorization.Message.Length + "bytes Complete:" + Authorization.Complete.ToString()); try { // // a "bad" module could try sending bad characters in the HTTP headers. // catch the exception from WebHeaderCollection.CheckBadChars() // fail the auth process // and return the exception to the user as InnerException // httpWebRequest.Headers.Set(AuthorizationHeader, Authorization.Message); } catch { Authorization = null; ClearSession(httpWebRequest); throw; } return true; }
// // attempts to authenticate the request: // returns true only if it succesfully called into the AuthenticationManager // and got back a valid Authorization and succesfully set the appropriate auth headers // internal bool AttemptAuthenticate(HttpWebRequest httpWebRequest, ICredentials authInfo) { // // Check for previous authentication attempts or the presence of credentials // GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() httpWebRequest#" + ValidationHelper.HashString(httpWebRequest) + " AuthorizationHeader:" + AuthorizationHeader.ToString()); if (Authorization!=null && Authorization.Complete) { // // here the design gets "dirty". // if this is proxy auth, we might have been challenged by an external // server as well. in this case we will have to clear our previous proxy // auth state before we go any further. this will be broken if the handshake // requires more than one dropped connection (which NTLM is a border case for, // since it droppes the connection on the 1st challenge but not on the second) // GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() Authorization!=null Authorization.Complete:" + Authorization.Complete.ToString()); if (IsProxyAuth) { // // so, we got passed a 407 but now we got a 401, the proxy probably // dropped the connection on us so we need to reset our proxy handshake // Consider: this should have been taken care by Update() // GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() ProxyAuth cleaning up auth status"); ClearAuthReq(httpWebRequest); } return false; } if (authInfo==null) { GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() authInfo==null Authorization#" + ValidationHelper.HashString(Authorization)); return false; } string challenge = httpWebRequest.AuthHeader(AuthenticateHeader); if (challenge==null) { // // the server sent no challenge, but this might be the case // in which we're succeeding an authorization handshake to // a proxy while a handshake with the server is still in progress. // if the handshake with the proxy is complete and we actually have // a handshake with the server in progress we can send the authorization header for the server as well. // if (!IsProxyAuth && Authorization!=null && httpWebRequest.ProxyAuthenticationState.Authorization!=null) { httpWebRequest.Headers.Set(AuthorizationHeader, Authorization.Message); } GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() challenge==null Authorization#" + ValidationHelper.HashString(Authorization)); return false; } // // if the AuthenticationManager throws on Authenticate, // bubble up that Exception to the user // GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() challenge:" + challenge); PrepareState(httpWebRequest); try { Authorization = AuthenticationManager.Authenticate(challenge, httpWebRequest, authInfo); } catch (Exception exception) { Authorization = null; GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::PreAuthIfNeeded() PreAuthenticate() returned exception:" + exception.Message); ClearSession(httpWebRequest); throw; } if (Authorization==null) { GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() Authorization==null"); return false; } if (Authorization.Message==null) { GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() Authorization.Message==null"); Authorization = null; return false; } UniqueGroupId = Authorization.ConnectionGroupId; GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() AuthorizationHeader:" + AuthorizationHeader + " blob: " + Authorization.Message.Length + "bytes Complete:" + Authorization.Complete.ToString()); try { // // a "bad" module could try sending bad characters in the HTTP headers. // catch the exception from WebHeaderCollection.CheckBadChars() // fail the auth process // and return the exception to the user as InnerException // httpWebRequest.Headers.Set(AuthorizationHeader, Authorization.Message); } catch { Authorization = null; ClearSession(httpWebRequest); throw; } return true; }
/// <devdoc> /// <para>Call each registered authentication module to determine the first module that /// can respond to the authentication request.</para> /// </devdoc> public static Authorization Authenticate(string challenge, WebRequest request, ICredentials credentials) { // // parameter validation // if (request == null) { throw new ArgumentNullException("request"); } if (credentials == null) { throw new ArgumentNullException("credentials"); } if (challenge == null) { throw new ArgumentNullException("challenge"); } GlobalLog.Print("AuthenticationManager::Authenticate() challenge:[" + challenge + "]"); Authorization response = null; HttpWebRequest httpWebRequest = request as HttpWebRequest; if (httpWebRequest != null && httpWebRequest.CurrentAuthenticationState.Module != null) { response = httpWebRequest.CurrentAuthenticationState.Module.Authenticate(challenge, request, credentials); } else { // This is the case where we would try to find the module on the first server challenge lock (s_ModuleBinding) { // // fastest way of iterating on the ArryList // for (int i = 0; i < ModuleList.Count; i++) { IAuthenticationModule authenticationModule = (IAuthenticationModule)ModuleList[i]; // // the AuthenticationModule will // 1) return a valid string on success // 2) return null if it knows it cannot respond // 3) throw if it could have responded but unexpectedly failed to do so // if (httpWebRequest != null) { httpWebRequest.CurrentAuthenticationState.Module = authenticationModule; } response = authenticationModule.Authenticate(challenge, request, credentials); if (response != null) { // // found the Authentication Module, return it // GlobalLog.Print("AuthenticationManager::Authenticate() found IAuthenticationModule:[" + authenticationModule.AuthenticationType + "]"); break; } } } } return(response); }