Constructing an OpenId provider, I've run into the curious problem that only Stack Exchange sites will accept it.
Discovery works fine, and watching log traffic I'm sending (what to me looks like) a valid response back.
Wonderfully, there are no compliance tests* to tell me what's wrong, nor do most sites which offer logins via OpenId give you any useful error messages. Stack Overflow gives some, but it seems to be the only relying party that just accepts my assertions, so... yeah.
Anyway, if I try to login to (for example) Typepad I ultimately redirect back to a url like
https://www.typepad.com/secure/services/signin/openid?openid-check=1&archetype.quickreg=1&tos_locale=en_US&portal=typepad&oic.time=1303249620-9db5665031c9c6b36031&openid.claimed_id=https://example/user/8c481fb7-1b5c-4e50-86b5-xxxxxxxxx&openid.identity=https://example/user/8c481fb7-1b5c-4e50-86b5-xxxxxxxxx&openid.sig=hoaxQrsN4BBg6H8kp50NoQwpHmcO96BBe+jB3oOP2UA=&openid.signed=claimed_id,identity,assoc_handle,op_endpoint,return_to,response_nonce,ns.alias3,alias3.mode&openid.assoc_handle={634388464235195799}{oqMrOA==}{32}&openid.op_endpoint=https://example/openid/provider&openid.return_to=https://www.typepad.com/secure/services/signin/openid?openid-check=1&archetype.quickreg=1&tos_locale=en_US&portal=typepad&oic.time=1303249620-9db5665031c9c6b36031&openid.response_nonce=2011-04-19T21:47:03Z1aa4NZ48&openid.mode=id_res&openid.ns=http://specs.openid.net/auth/2.0&openid.ns.alias3=http://openid.net/srv/ax/1.0&openid.alias3.mode=fetch_response
Broken out for (slightly) easier reading:
openid-check=1
archetype.quickreg=1
tos_locale=en_US
portal=typepad
oic.time=1303249620-9db5665031c9c6b36031
openid.claimed_id=https://example/user/8c481fb7-1b5c-4e50-86b5-xxxxxxxxx
openid.identity=https://example/user/8c481fb7-1b5c-4e50-86b5-xxxxxxxxx
openid.sig=hoaxQrsN4BBg6H8kp50NoQwpHmcO96BBe+jB3oOP2UA=
openid.signed=claimed_id,identity,assoc_handle,op_endpoint,return_to,response_nonce,ns.alias3,alias3.mode
openid.assoc_handle={634388464235195799}{oqMrOA==}{32}
openid.op_endpoint=https://example/openid/provider
openid.return_to=https://www.typepad.com/secure/services/signin/openid?openid-check=1
archetype.quickreg=1
tos_locale=en_US
portal=typepad
oic.time=1303249620-9db5665031c9c6b36031
openid.response_nonce=2011-04-19T21:47:03Z1aa4NZ48
openid.mode=id_res
openid.ns=http://specs.openid.net/auth/2.0
openid.ns.alias3=http://openid.net/srv/ax/1.0
openid.alias3.mode=fetch_response
Here's XRDS for the user (since discovery seems ok).
<?xml version="1.0" encoding="UTF-8"?>
<xrds:XRDS
xmlns:xrds="xri://$xrds"
xmlns:openid="http://openid.net/xmlns/1.0"
xmlns="xri://$xrd*($v*2.0)">
<XRD>
<Service priority="10">
<Type>http://specs.openid.net/auth/2.0/signon</Type>
<LocalID>https://example/user/8c481fb7-1b5c-4e50-86b5-xxxxxxxxx</LocalID>
<Type>http://openid.net/extensions/sreg/1.1</Type>
<Type>http://axschema.org/contact/email</Type>
<URI>https://example/openid/provider</URI>
</Service>
<Service priority="20">
<Type>http://openid.net/signon/1.0</Type>
<Type>http://openid.net/extensions/sreg/1.1</Type>
<Type>http://axschema.org/contact/email</Type>
<URI>https://example/openid/provider</URI>
</Service>
</XRD>
</xrds:XRDS>
If you dig into TypePad's html, you find the following error message
<!-- Error Code: unexpected_url_redirect -->
... which is why I use them as an example. Kind of useless, but its something.
This code is very heavily based on the example MVC project that ships with dotNetOpenAuth, the SendAssertion implementation is where I suspect things are getting ill.
protected ActionResult SendAssertion(IAuthenticationRequest authReq)
{
// Not shown: redirect to a prompt if needed
if (authReq.IsDirectedIdentity)
{
authReq.LocalIdentifier = Current.LoggedInUser.GetClaimedIdentifier();
}
if (!authReq.IsDelegatedIdentifier)
{
authReq.ClaimedIdentifier = authReq.LocalIdentifier;
}
authReq.IsAuthenticated = this.UserControlsIdentifier(authReq);
if (authReq.IsAuthenticated.Value)
{
// User can setup an alias, but we don't actually want relying parties to store that since it can change over time
authReq.ClaimedIdentifier = Current.LoggedInUser.GetClaimedIdentifier();
authReq.LocalIdentifier = Current.LoggedInUser.GetClaimedIdentifier();
// Not shown: responding to AX and SREG requests
}
var req = OpenIdProvider.PrepareResponse(authReq);
var ret = req.AsActionResult();
return ret;
}
Sorry this is such a huge info dump, but I haven't got a lot to go on and accordingly can't really narrow it down to something simple.
So I guess the ultimate question is... any ideas what I'm doing wrong here?
*OK, there are sort of tests. But nothing says "ah-ha, this is broken."
There turned out to be a whole bunch of other gotchas here, none of them really pertaining to dotNetOpenAuth.
/
, which broke discoveryopenid.server
in the returned HTML.dotNetOpenAuth as one of the (apparently few) OpenId libraries out there that can do the whole OpenId dance over headers worked just fine, by coincidence.
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