[OpenID] Only 303, not temp redirects (302/307), need changing

John Kemp john at jkemp.net
Fri Mar 7 15:33:28 UTC 2008


Hello,

Manger, James H wrote:
> Noah said:
> "also consider changing the rules for 302 and 307 redirects
> which are both clearly temporary and should not be canonicalised."
> 
> 
> NO.

Sorry, but I don't fully agree.

> These temporary redirects (302 and 307) provide a path
> between what the user types into an RP and their claimed_id.

If the user types <http://example.com/john> and he has setup a 302 to 
<http://example.com/docs/services.xrds>, then the RPs claimed ID is the 
latter, not the former with OpenID today.

That's not what the user typed in at the RP. And probably, the /user/ 
wants to use the former as his OpenID, not the latter.

Let's imagine that the OP is the one who has set up this temporary 
redirect. Why would it do that? Does the user even know? But which 
identifier does the OP want to assert for the user? The one the /user/ 
chose, or the one that it temporarily is using?

> This path is chosen by the user.

It is not chosen by the non-superuser user.

> It is particularly important
> for a well-defined, widely-used, security-critical use case:
> * the user enters "example.net" at the RP;
> * the RP changes this text to "http://example.net/" and does a GET;
> * the website returns a 307 Temporary Redirect to "https://example.net/";
> * the RP does another GET, secured with TLS, receiving the OP details;
> The claimed_id is "https://example.net/".

Now we get into something else "icky" about OpenID URIs. How are two 
URIs thought to be equivalent, especially if the user didn't choose one? 
Just because the only difference is in the scheme, how can we be sure 
that they are the same?

My answer would be that the OP should setup a 301 PERMANENT redirect to 
the https URI, based on its relationship with the user. In which case, 
OpenID discovery redirections should be followed.

> This is an important feature. One benefit is allowing users to use
> more secure (https) OpenIDs without having to type in longer strings.
> 

Agreed that this is important.

> This behaviour does NOT violate HTTP. It must not be changed.
> A change would be appalling for backward compatibility as lots of
> 302/307s are used.

One thing I would just note here is that I don't think it matters very 
much (to OpenID) if OpenID "violates" HTTP semantics (note: that I'm not 
saying whether it matters to me personally or not ;)

What /is/ important is that OpenID does what the user (and OP) expects. 
And one way to help that is to use HTTP in the manner in which it is 
documented.

> 
> The claimed_id should change with these redirects -- as OpenID specifies.

As mentioned, I don't agree.

> An RP should think of these redirects as the user's choice of a path from
> what they type to their claimed_id. The possibility of temporary redirects
> (307 or 302) is a reminded to the RP that it must not use the user-entered
> identifier as an index into its account database. It must wait until it has
> a claimed_id to know which account the user is trying to login to.
> A RP does not need to worry that a temporary redirect may change
> in future. It may change, but that means the user has chosen to map that
> user-entered identifier to a different OpenID (a different account
> at the RP). The user can still access the original account by entering
> the original claimed_id.

See my example above. This is almost exactly the example that Sam Ruby 
originally used to illustrate his point.

> 
> A 301 Moved Permanently is in the same boat as 302 & 307.
> These three response codes all mean:
>   "The request HAS NOT succeeded. Try it again at a new URI."

That's not what RFC 2616 says 
(http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html)

302 Found and 307 Temporary Redirect do not indicate any kind of failure 
semantics.

And if the request obtaining a 301, 302, 303, or 307 is not a GET or a 
HEAD, RFC2616 says that the user-agent MUST NOT redirect without asking 
the user.

> => "This is NOT the claimed_id. Try this new URI."
> 
> 
> A 303 See Other response has a different meaning to 301/302/307. It means:
>   "The request HAS succeeded. Response data can be collected at a new URI."
> => "This is the claimed_id. Get the OP details from a new URI."
> OpenID/XRDS/Yadis has its own version of 303 -- the X-XRDS-Location header.
> A response with such a header means:
>   "The request HAS succeeded (you have reached the claimed_id).
>   The OP details (in an XRDS file) are available from a new URI."
> The specification of X-XRDS-Location is quite clear that the claimed_id
> is the URI that returned the X-XRDS-Location header, not the URI listed in
> that header.
> HTTP defines 303 See Other to have the same sort of semantics as
> OpenID defines for X-XRDS-Location. OpenID should treat a 303 much like it
> treats X-XRDS-Location: don't change the claimed_id to the new URI.
> 
> The similarity between 303 and X-XRDS-Location also highlights that there
> are NO SECURITY PROBLEMS with treating 303 as per the HTTP spec since
> the security implications are identical to X-XRDS-Location.
> 
> 
> As for user intentions with respect to a temporary redirect (A to B),
> I see two user perspectives. There will be users with each perspective.
> 1. "I want entering A to be a shortcut for logging in with identity B";
> 2. "I want A to be my identity, but the OP details are temporarily at B".
> At the moment OpenID assumes #1.
> At least Sam Ruby, Noah, Brendan and I want #2.
> Properly supporting HTTP 303 would allow users to be explicit:
> 301/302/307 implies #1,
> 303 implies #2.

I don't agree that 303 implies #2. 303 implies a PERMANENT relationship 
between the identifier the user chose, and some other document at some 
other URI. I think though that Sam's use-case probably suggests that 303 
would be the right choice for what he is doing.

I see that a 302/307 temporary redirect is something that an OP might 
set up without a user even knowing.

Here would be my documentation rules:

i) An OP wishing to redirect ALL http URLs to use https, if they have 
already issued http URLs to users should set up HTTP 301 Permanent 
Redirect from the issued http URL to the https URL.
ii) An OP (or user delegating) wishing to provide a permanent link from 
their issued OpenID to another resource containing their discovery 
information (XRDS/YADIS) should create a 303 See Other redirect from 
their OpenID to their XRDS document. This implies that the RP MUST NOT 
follow redirects in establishing the claimed ID.
iii) An OP wishing to provide a temporary change in the location of 
OpenID discovery information for a given OpenID URL should create a 302 
(HTTP/1.0) Found or 307 (HTTP/1.1) Temporary Redirect from the OpenID 
URL. This implies that the RP MUST NOT follow redirects.

Note that ii) and  iii) would require normative spec. changes. If such 
changes don't happen then there are two alternatives:

a) That OPs and users can't use redirects to indicate particular 
relationships between the OpenIDs they have and related resources (such 
as an XRDS file) or the effect of a temporary redirect made by their OP 
without the user's knowledge.
b) That "implementation guidelines" for OPs suggest that in the above 
cases, the OP should assert a different ID to the RP than the claimed 
ID, depending on the OP's intent. In other words, the OP has to do a bit 
more work if OpenID doesn't use HTTP semantics optimally.

If we can't agree on making spec. changes but we can agree on something 
like the above, I would be happy to write up this discussion on the wiki.

Cheers,

- johnk



More information about the general mailing list