I'm having trouble getting a DNOA RP working behind an SSL appliance (terminates the client HTTPS connection and reverse-proxies HTTP to the webserver behind it).
The problem is that the RP is incorrectly guessing the recipient endpoint from the incoming request (since it's not HTTPS by the time it hits the webserver) and comparing the endpoint with scheme on the return_to url (which is HTTPS)- it fails with the stacktrace below. I've spelunked around in the code a bit and I don't see a way to change this behavior without a custom build or a non-trivial subclass. I'm already passing the HTTPS version of the Realm and ReturnToUrl to OpenIdRelyingParty.CreateRequests()- that part's working fine.
Is it possible to fudge the detected recipient scheme to HTTPS or skip scheme comparison on a stock DNOA build, or am I patching up a custom build tomorrow?
Stacktrace:
ERROR DotNetOpenAuth.Messaging - 09 Jul 2010 00:11:39,450 - Protocol error: The openid.return_to parameter (https://XXX/Login.aspx?openid=XXX&dnoa.userSuppliedIdentifier=XXX) does not match the actual URL (http://XXX/Login.aspx?openid=XXX&dnoa.userSuppliedIdentifier=XXX&openid.ns=http://specs.openid.net/auth/2.0&openid.mode=id_res&openid.op_endpoint=XXX&openid.response_nonce=XXX&openid.return_to=https://XXX/Login.aspx?openid=XXX&dnoa.userSuppliedIdentifier=XXX&openid.assoc_handle=XXX&openid.signed=op_endpoint,claimed_id,identity,return_to,response_nonce,assoc_handle&openid.sig=XXX&openid.identity=XXX&openid.claimed_id=XXX) the request was made with.
at DotNetOpenAuth.Messaging.ErrorUtilities.VerifyProtocol(Boolean condition, String message, Object[] args)
at DotNetOpenAuth.OpenId.Messages.IndirectSignedResponse.VerifyReturnToMatchesRecipient()
at DotNetOpenAuth.OpenId.Messages.IndirectSignedResponse.EnsureValidMessage()
at DotNetOpenAuth.Messaging.MessageSerializer.Deserialize(IDictionary`2 fields, MessageDictionary messageDictionary)
at DotNetOpenAuth.Messaging.Reflection.MessageDictionary.Deserialize(IDictionary`2 fields)
at DotNetOpenAuth.Messaging.Channel.Receive(Dictionary`2 fields, MessageReceivingEndpoint recipient)
at DotNetOpenAuth.Messaging.Channel.ReadFromRequestCore(HttpRequestInfo request)
at DotNetOpenAuth.Messaging.Channel.ReadFromRequest(HttpRequestInfo httpRequest)
at DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingParty.GetResponse(HttpRequestInfo httpRequestInfo)
at DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingParty.GetResponse()
DotNetOpenAuth has built-in support for SSL appliances when they add these special HTTP headers to the forwarded HTTP request: X_FORWARDED_PROTO
and/or HTTP_HOST
. When these are present, the auto-detection of the outside-facing URL is correct. If you can configure your SSL appliance to do this, that's probably the best option.
The alternative is to call OpenIdRelyingParty.GetResponse(HttpRequestInfo)
instead of the overload that takes no parameters. You construct the HttpRequestInfo
yourself using the outward-facing URL that you know is the real one. Then the URL matching logic inside DotNetOpenAuth won't fail the request.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With