Subject: [OAUTH-WG] Returning HTTP 200 on Error for JSONP

From: Paul Tarjan <[email-masked]>
Date: Fri, 13 Aug 2010 21:31:05 +0000

Hi Fellow OAuthers,

If a resource wants to return data via the JSONP mechanism then it MUST return an HTTP 200 error code, or else the browser won't actually call the callback. The OAuth spec as it stands requires HTTP 400 or 401 or 403 on errors which won't ever tell the client that an error happens.

For example:

GET /me?callback=jsonp_cb HTTP/1.1
Host: graph.facebook.com<http://graph.facebook.com/>

HTTP/1.1 200 OK
Content-Type: text/javascript; charset=UTF-8
Content-Length: 152

jsonp_cb({
   "error": "invalid_request",
   "error_description": "An active access token must be used to query information about the current user."
});

would never get sent to the browser if we obeyed the spec and sent it as an HTTP 400.

---
So, I recommend we add wording to 5.2.1 like:

If the protected resource is issuing a response that requires a different HTTP status code than the one specified (for example, JSONP), then it MAY use an alternate HTTP code. The server should make it clear which parameters trigger this mode so that clients know not to rely on the HTTP status code for error detection.

Paul

---

From: Luke Shepard <[email-masked]>
Date: Mon, 16 Aug 2010 05:16:51 +0000

+1

On Aug 13, 2010, at 2:31 PM, Paul Tarjan wrote:

Hi Fellow OAuthers,

For example:

HTTP/1.1 200 OK

jsonp_cb({

---

Paul
_______________________________________________
OAuth mailing list
[email-masked]<mailto:[email-masked]>
https://www.ietf.org/mailman/listinfo/oauth

---

From: Aaron Parecki <[email-masked]>
Date: Mon, 16 Aug 2010 08:49:29 -0700

Excellent point. Would it be worth it to include a new error_code parameter
in the JSON response so that clients have a way to get the http status code
from the data available in the jsonp response?

The response in this case might look like this
jsonp_cb({
   "error_code": 400,
   "error": "invalid_request",
   "error_description": "An active access token must be used to query
information about the current user."
});

Aaron

On Sun, Aug 15, 2010 at 10:16 PM, Luke Shepard <[email-masked]>wrote:

> If a resource wants to return data via the JSONP mechanism then it MUST
> return an HTTP 200 error code, or else the browser won't actually call the
> callback. The OAuth spec as it stands requires HTTP 400 or 401 or 403 on
> errors which won't ever tell the client that an error happens.
>
> For example:
>
> Host: graph.facebook.com
> If the protected resource is issuing a response that requires a different
> HTTP status code than the one specified (for example, JSONP), then it MAY
> use an alternate HTTP code. The server should make it clear which parameters
> trigger this mode so that clients know not to rely on the HTTP status code
> for error detection.
>
>
> Paul
> [email-masked]
> [email-masked]

---

From: John Panzer <[email-masked]>
Date: Mon, 16 Aug 2010 09:11:51 -0700

Is there ever a case other than jsonp where this is necessary?

On Monday, August 16, 2010, Aaron Parecki <[email-masked]> wrote:
> Excellent point. Would it be worth it to include a new error_code
> parameter in the JSON response so that clients have a way to get the
> http status code from the data available in the jsonp response?
>
> On Sun, Aug 15, 2010 at 10:16 PM, Luke Shepard <[email-masked]> wrote:
>
>
> +1
>
> Host: graph.facebook.com <http://graph.facebook.com/>
>
> HTTP/1.1 200 OK
> jsonp_cb({   "error": "invalid_request",   "error_description": "An active access token must be used to query information about the current user."
> });
> Paul_______________________________________________
> OAuth mailing list
> [email-masked]

-- 
--
John Panzer / Google
[email-masked] / abstractioneer.org / @jpanzer

---

From: Torsten Lodderstedt <[email-masked]>
Date: Tue, 17 Aug 2010 00:09:29 +0200

I would like to furthermore track down the relevant use cases. Assuming 
you are referring to section 5.2.1, how does your client send the access 
token to the resource server? I'm asking because I think error handling 
for URI query parameters, Body parameters and Authorization headers 
could be handled differently. For URI query parameters and Body 
parameters, returning the error code in the payload instead of the 
status code would be acceptable from my point of view since 
authentication is also pushed to the application level. In contrast when 
using HTTP authentication, 40(x) status codes together with 
WWW-Authenticate are a must have.

Would such a differentiation help you?

regards,
Torsten.

---

From: Paul Tarjan <[email-masked]>
Date: Tue, 17 Aug 2010 00:29:00 +0000

Yes, I'm talking about 5.2.1

For JSONP the user's browser is the client. It will make a request by executing some HTML like this:

<script src="http://graph.facebook.com/me?access_token=...&callback=jsonp_cb"></script>
<script>
function jsonp_cb(response) {
  if (response.error) {
    // error out
   return;
  }
  // do cool things
}
</script>

(this is done instead of an AJAX request, because of cross-domain restrictions).

As to Aaron's point, Google sends 3 parameters to the callback function, which I kind of like since the user can choose to get the code or not. Something like:

jsonp_cb({
}.
400,
'Bad Request');

which you can grab with

function jsonp_cb(response, code, status) {
}

or ignore it with

function jsonp_cb(response) {
}

But all of this is outside of the spec. I just want to make sure the spec says that the HTTP status code can send as 200 if the server+client need it for errors.

Paul

On Aug 16, 2010, at 3:09 PM, Torsten Lodderstedt wrote:

> I would like to furthermore track down the relevant use cases. Assuming you are referring to section 5.2.1, how does your client send the access token to the resource server? I'm asking because I think error handling for URI query parameters, Body parameters and Authorization headers could be handled differently. For URI query parameters and Body parameters, returning the error code in the payload instead of the status code would be acceptable from my point of view since authentication is also pushed to the application level. In contrast when using HTTP authentication, 40(x) status codes together with WWW-Authenticate are a must have.
>

---

From: Torsten Lodderstedt <[email-masked]>
Date: Tue, 17 Aug 2010 08:02:31 +0200

> But all of this is outside of the spec. I just want to make sure the spec says that the HTTP status code can send as 200 if the server+client need it for errors.
I think this can be achieved in two ways: (a) either the client tells 
the server using a parameter or (b) the server always responds with 
status code 200 in some cases. From my understanding, status code 200 is 
relevant for requests following the rules of section 5.1.2 only. So my 
sugesstion would be to go with option (b) and modify the spec to always 
return status code 200 for such requests. This keeps the spec simpler 
and preserves the behavior of requests following the rules of section 
5.1.1..

regards,
Torsten.

---

From: John Panzer <[email-masked]>
Date: Tue, 17 Aug 2010 00:28:54 -0700

Except you cannot guarantee that result of course (proxies, apache
plus tomcat separate processes etc. will all result in error codes).

Doesn't this all depend on a jsonp extension in the first place - the
client has to request a special jsonp response by specifying the
callback, thus making the server both use 200s where possible and also
wrap its response data in a callback call?  That's not part of the
spec either, why not just define both pieces of behavior in a jsonp
extension spec?  (Assuming this can be done without violating the
letter of the core spec, which might take some wordsmithing.)

On Monday, August 16, 2010, Torsten Lodderstedt <[email-masked]> wrote:
> I think this can be achieved in two ways: (a) either the client tells the server using a parameter or (b) the server always responds with status code 200 in some cases. From my understanding, status code 200 is relevant for requests following the rules of section 5.1.2 only. So my sugesstion would be to go with option (b) and modify the spec to always return status code 200 for such requests. This keeps the spec simpler and preserves the behavior of requests following the rules of section 5.1.1..
>
> regards,
> Torsten.
>
>
> Paul
>

---

From: Torsten Lodderstedt <[email-masked]>
Date: Tue, 17 Aug 2010 09:43:28 +0200

Good point. The server will have to provide special JSONP support anyway. This is the only place where the requested status code handling is needed.

+1 for a JSONP extension spec

This might also result in much cleaner JSONP support.

regards,
Torsten.

---

From: Luke Shepard <[email-masked]>
Date: Tue, 17 Aug 2010 15:22:40 +0000

>From the perspective of OAuth, a JSONP endpoint is just another protected resource. I'd rather not need us to write an extension for every type of protected resource we might need to access.

I think the wordsmithing you discussed is what Paul's proposing - just saying essentially "look, these are the HTTP error codes you can expect, but it's okay for the server sometimes to give 200 on an error response anyway". That would be necessary even if we wrote an extension.

---

From: John Panzer <[email-masked]>
Date: Tue, 17 Aug 2010 09:06:05 -0700

Well, no, jsonp is a special transport layer inside http.  Making that
fuzzy will cause (interop and security) problems.

On Tuesday, August 17, 2010, Luke Shepard <[email-masked]> wrote:
>>>> Would such a

---

From: David Recordon <[email-masked]>
Date: Tue, 17 Aug 2010 11:48:39 -0700

Luke's point still holds true of the core spec needing to allow a 200 status
code on an error in this scenario. I'd also rather see this as part of the
core spec as it reduces the number of things that implementors will need to
read for common use cases.

--David

On Tue, Aug 17, 2010 at 9:06 AM, John Panzer <[email-masked]> wrote:

> > From the perspective of OAuth, a JSONP endpoint is just another protected
> resource. I'd rather not need us to write an extension for every type of
> protected resource we might need to access.
> >
> > I think the wordsmithing you discussed is what Paul's proposing - just
> saying essentially "look, these are the HTTP error codes you can expect, but
> it's okay for the server sometimes to give 200 on an error response anyway".
> That would be necessary even if we wrote an extension.
> >
> >> Good point. The server will have to provide special JSONP support
> anyway. This is the only place where the requested status code handling is
> needed.
> >>
> >>>> <script src="
> http://graph.facebook.com/me?access_token=...&callback=jsonp_cb"></script>
> >>>> <script>
> >>>> As to Aaron's point, Google sends 3 parameters to the callback
> function, which I kind of like since the user can choose to get the code or
> not. Something like:
> >>>>
> >>>> jsonp_cb({
> >>>> But all of this is outside of the spec. I just want to make sure the
> spec says that the HTTP status code can send as 200 if the server+client
> need it for errors.
> >>>>
> >>>>
> the server using a parameter or (b) the server always responds with status
> code 200 in some cases. From my understanding, status code 200 is relevant
> for requests following the rules of section 5.1.2 only. So my sugesstion
> would be to go with option (b) and modify the spec to always return status
> code 200 for such requests. This keeps the spec simpler and preserves the
> behavior of requests following the rules of section 5.1.1..
> >>>>
> >>>> regards,
> >>>> Torsten.
> >>>>
> >>>>
> >>>> Paul
> >>>>
> >>>> I would like to furthermore track down the relevant use cases.
> Assuming you are referring to section 5.2.1, how does your client send the
> access token to the resource server? I'm asking because I think error
> handling for URI query parameters, Body parameters and Authorization headers
> could be handled differently. For URI query parameters and Body parameters,
> returning the error code in the payload instead of the status code would be
> acceptable from my point of view since authentication is also pushed to the
> application level. In contrast when using HTTP authentication, 40(x) status
> codes together with WWW-Authenticate are a must have.
> >>>>
> >>>> Would such a
>
> --
> --
> John Panzer / Google

---

From: John Panzer <[email-masked]>
Date: Tue, 17 Aug 2010 16:06:32 -0700

Sure - as long as this is tied to the very special case of a tunneled
protocol over http.

On Tuesday, August 17, 2010, David Recordon <[email-masked]> wrote:
> Luke's point still holds true of the core spec needing to allow a 200 status code on an error in this scenario. I'd also rather see this as part of the core spec as it reduces the number of things that implementors will need to read for common use cases.
>
> --David
>
>>>>> I think this can be achieved in two ways: (a) either the client tells the server using a parameter or (b) the server always responds with status code 200 in some cases. From my understanding, status code 200 is relevant for requests following the rules of section 5.1.2 only. So my sugesstion would be to go with option (b) and modify the spec to always return status code 200 for such requests. This keeps the spec simpler and preserves the behavior of requests--
> --
> John Panzer / Google

---

From: Brian Eaton <[email-masked]>
Date: Tue, 17 Aug 2010 17:30:23 -0700

> read for common use cases.

For the record, I think any implementer that is relying on protected
resources returning special response codes for any type of OAuth
protocol issue is probably going to get burned.  Variation in
protected resource behavior has been a consistent problem in OAuth
1.0, and I doubt that can change in OAuth 2.

It's tough to get protected resource servers to be consistent; they
frequently have good reasons (e.g. jsonp) to be inconsistent.

Authorization servers are simpler beasts.

---

From: John Panzer <[email-masked]>
Date: Tue, 17 Aug 2010 19:33:58 -0700

Is there any legit reason other than jsonp specifically?

In the wild I mean.

---

From: Mark Nottingham <[email-masked]>
Date: Wed, 18 Aug 2010 16:15:37 +1000

...and tunneling protocols over HTTP have worked *so* well in the past...

*makes another drink to help forget the SOAP nightmares*

back to your regular programming...

--
Mark Nottingham     http://www.mnot.net/

---

From: Brian Eaton <[email-masked]>
Date: Tue, 17 Aug 2010 22:57:58 -0700

> Is there any legit reason other than jsonp specifically?

Protected resource authors are slack and are not going to read the
spec.  That might not be a great reason, but it's not a bad one
either.

The other reason people get funny with these status codes has to do
with browser behavior.  Sometimes browsers react in funny ways to
funny HTTP status codes.  To be on the safe side, developers tend to
return an HTTP 200 with whatever they want the user to see.

The last reason is that servers fail, and instead of returning the
error they meant to return they serve up a bit of static HTML that
says, more or less, "Whoa.  That sucked."

---

From: Mark Nottingham <[email-masked]>
Date: Wed, 18 Aug 2010 16:36:34 +1000

> return an HTTP 200 with whatever they want the user to see.

Can you give concrete examples, please? What browsers do what exactly, under what circumstances?

---

From: Eran Hammer-Lahav <[email-masked]>
Date: Wed, 18 Aug 2010 00:00:09 -0700

I disagree.

The sole purpose of the specification is to achieve interop. By creating this exception for JSONP calls, you are breaking interop with non JSONP clients. For this to work, you need to specify exactly when this exception happens, and how to deliver the HTTP status code to the client. This sounds like a specification. For example, how is the client going to get the original HTTP status code?

This is not a legal document, and you are free to implemented it differently if you do it in a way that does not harm interop. In this case, you are basically proposing changing a MUST to a SHOULD, which takes away any interop value the requirement has in the first place (ie. being predictable and consistent).

If JSONP is an important use case, and if it should be consistently implemented across services, then it needs to be specified and such a specification can clear override the core specification directive on HTTP status code. I don't know where people got the idea that other specifications cannot modify requirements in the core specification - that's just silly. As long as you spell it out and provide enough detail to maintain interop with the new work, it is perfectly fine. This is not the constitution.

As for the argument that developers are not going to read so many specification, so core should address it - that's also silly. Most developers are never going to read the specification. At best, they will read the vendor API docs.

For the record, I have no objection to the core specification fully addressing the JSONP use case. But I'm opposed to making such an underspecified exception.

EHL

From: [email-masked] [mailto:[email-masked]] On Behalf Of Paul Tarjan
Sent: Friday, August 13, 2010 2:31 PM
To: OAuth WG
Subject: [OAUTH-WG] Returning HTTP 200 on Error for JSONP

Hi Fellow OAuthers,

For example:

HTTP/1.1 200 OK

---

Paul

---

From: Luke Shepard <[email-masked]>
Date: Wed, 18 Aug 2010 07:12:28 +0000

For example, how is the client going to get the original HTTP status code?

Why does the client need the HTTP status code? It seems like the real data is the OAuth error code (i.e., "invalid request"). The HTTP status code is just gravy so that we're consistent with HTTP.

Okay ... so why are we specifying HTTP codes at all then? Since we have clearly defined the error types, why is it wrong to say "use whatever HTTP code you think is right, here are some suggestions"?

If JSONP is an important use case

It is.

and if it should be consistently implemented across services, then it needs to be specified and such a specification can clear override the core specification directive on HTTP status code.

I dunno, JSONP is pretty commonly implemented across lots of services today. You typically pass in the parameter "callback" and then that prepends your response. I'm not aware of a specification for it, but convention + copying each other has made services somewhat consistent in this.

In any case, I don't think this group should be held up by writing a new spec just to address this one use case.

I don’t know where people got the idea that other specifications cannot modify requirements in the core specification – that’s just silly. As long as you spell it out and provide enough detail to maintain interop with the new work, it is perfectly fine. This is not the constitution.

(The Constitution allows amendments, too - but similarly, it's a lot of work)

From: [email-masked]<mailto:[email-masked]> [mailto:[email-masked]] On Behalf Of Paul Tarjan
Sent: Friday, August 13, 2010 2:31 PM
To: OAuth WG
Subject: [OAUTH-WG] Returning HTTP 200 on Error for JSONP

Hi Fellow OAuthers,

For example:

HTTP/1.1 200 OK

---

Paul

---

From: Eran Hammer-Lahav <[email-masked]>
Date: Wed, 18 Aug 2010 00:18:13 -0700

From: Luke Shepard [mailto:[email-masked]]
Sent: Wednesday, August 18, 2010 12:12 AM
To: Eran Hammer-Lahav
Cc: Paul Tarjan; OAuth WG
Subject: Re: [OAUTH-WG] Returning HTTP 200 on Error for JSONP

There is nothing wrong with saying that, if we decide that there is no interop value in specifying them. Pointing to the HTTP spec and say follow that is perfectly fine. But as currently written, since the codes are prescribed, clients are allowed to rely on them, which will lead to problems.

EHL

It is.

I don't know where people got the idea that other specifications cannot modify requirements in the core specification - that's just silly. As long as you spell it out and provide enough detail to maintain interop with the new work, it is perfectly fine. This is not the constitution.

Hi Fellow OAuthers,

For example:

HTTP/1.1 200 OK

---

Paul

---

From: Brian Eaton <[email-masked]>
Date: Wed, 18 Aug 2010 08:55:46 -0700

> Can you give concrete examples, please? What browsers do what exactly, under what circumstances?

Here's a well-known example:
http://malektips.com/internet-explorer-8-disable-friendly-error-messages.html.

Fuzzier stuff is in handling of things like WWW-Authenticate headers
on HTTP 200 responses, or 401s with unknown authorization challenges.

---

From: John Panzer <[email-masked]>
Date: Wed, 18 Aug 2010 09:18:37 -0700

For ie silliness, sop is to include a lot of text in the 5xx so it'll
show your message instead of its own.

I've done lots of www-authenticate with 200's, always heard worries
from web engineers, never had a bug report.  Ymmv.

---

From: Mark Nottingham <[email-masked]>
Date: Thu, 19 Aug 2010 08:47:45 +1000

See:
  http://support.microsoft.com/kb/294807

---

From: Mark Nottingham <[email-masked]>
Date: Fri, 20 Aug 2010 09:00:55 +1000

How fortuitous: 
  http://blogs.msdn.com/b/ieinternals/archive/2010/08/19/http-error-pages-in-internet-explorer.aspx

---

From: <[email-masked]>
Date: Fri, 20 Aug 2010 13:19:53 +0200

http://www.readwriteweb.com/cloud/2010/08/the-new-api-movement-may.php
See #10  

-Axel

---

From: George Fletcher <[email-masked]>
Date: Fri, 20 Aug 2010 09:09:30 -0400

I believe Flash (in the browser) has similar constraints. Don't know 
about Silverlight.

Thanks,
George

On 8/17/10 10:33 PM, John Panzer wrote:
> On Tuesday, August 17, 2010, Brian Eaton<[email-masked]>  wrote:
>> On Tue, Aug 17, 2010 at 11:48 AM, David Recordon<[email-masked]>  wrote:

---

From: Robert Sayre <[email-masked]>
Date: Mon, 23 Aug 2010 19:28:08 -0400

> Is there any legit reason other than jsonp specifically?

The JSONP response doesn't add any value, so it isn't a legitimate
reason anyway.
-- 

Robert Sayre

"I would have written a shorter letter, but I did not have the time."