Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include-Referer-Token-Binding-ID header meaningful beyond HTTP 302/1? #10

Closed
b---c opened this issue Apr 20, 2015 · 12 comments
Closed

Include-Referer-Token-Binding-ID header meaningful beyond HTTP 302/1? #10

b---c opened this issue Apr 20, 2015 · 12 comments

Comments

@b---c
Copy link
Contributor

b---c commented Apr 20, 2015

I mentioned this briefly on mic at the Dallas IETF meeting but wanted to put it in as an issue too so it doesn't get lost.

In section 3.3 the Include-Referer-Token-Binding-ID header "only [has] meaning if the HTTP status code is 302 or 301, and MUST be ignored by the client for any other status codes."

in existing federation protocols, however, it is not uncommon for what this draft calls the "token request" to be delivered in other ways. Notably via POST.

In SAML 2.0, for example, an AuthnRequest message may be sent from SP to IDP via the HTTP POST Binding (see sec 5 of SAML Bindings). And less common but still possible is the use of auto submit form for delivery of an artifact reference to the AuthnRequest message (sec 3.6.3.3 of SAML Bindings).

OAuth allows for a POST to the Authorization Endpoint via a MAY in sec 3.1, which might be accomplished by the RP/Token Consumer using a similar technique as in a SAML POST of encoding the message in HTML form controls that are posted to the IDP/Token Provider. And OpenID Connect requires that the OP/AS/Token Producer support POST at the Authorization Endpoint in sec 3.1.2.1.

One could also imagine the Token Consumer returning content to the user/client that has links or something on it, which would result in directly navigating the user to the Token Provider.

So it seems like maybe the scope of Include-Referer-Token-Binding-ID header being meaningful should be expanded a bit to include navigation off of content delivered to the client via HTTP 200 (and maybe more but that's the case that I can come up with).

@balfanz
Copy link
Member

balfanz commented Jun 30, 2015

XHRs, POSTs, etc. will be handled by fetch() in the future. We should therefore discuss over there how to best signal to the UA that it should include the referred token-binding ID in the request to the IdP. In this spec, I'll stick to just the redirect-based mechanism.

@b---c
Copy link
Contributor Author

b---c commented Jun 30, 2015

Dirk, the use cases I'm talking about are different than XHR/fetch(). It's an old school HTML form POST. It is often, though not necessarily always, triggered by javascript. Really it's a trick to get 302 like behavior from the browser but that results in a POST request to the location rather than a GET.

Please re-open / re-consider.

@balfanz balfanz reopened this Jun 30, 2015
@balfanz
Copy link
Member

balfanz commented Jun 30, 2015

If I understand correctly, in the future these "old school" form POSTs will all be handled by fetch(), i.e., you won't make a fetch() API call (you still just have a <form action="...">), but the POST will be handled by the same stack that also handles the fetch() requests (and, indeed, all the HTTP request fetching).

So I'm imagining something like

<form action="https://idp.com/oauth-authz" 
      method="post" 
      include-referer-token-binding="true">
...
</form>

to trigger the inclusion of the referred token binding, but since that POST will be handled by the fetch() stack, we should discuss whether this particular new include-referer-token-binding attribute (or some other mechanism) is best, over there. Does this make sense?

@annevk
Copy link

annevk commented Jun 30, 2015

@b---c how does <form> enable you to get a POST? You haven't really explained the full setup so that makes it very hard to reason about things.

Note that 307 and 308 are both designed to retain method semantics in a redirect due to browsers misimplementing 301 and 302 (for POST, other methods should work fine).

@b---c
Copy link
Contributor Author

b---c commented Jul 1, 2015

@balfanz, that makes some sense. I guess I'd imagined a solution where draft-ietf-tokbind-https would expand Include-Referer-Token-Binding-ID to also have meaning for HTTP status code 200, where any full navigation off of the page returned by the 200 would include referred_token_binding. I'm not saying that's the right approach but just wanted to explain my thinking a bit more. What you've got there would work too and is more targeted, which is probably a good thing.

@b---c
Copy link
Contributor Author

b---c commented Jul 1, 2015

Sorry @annevk , I cited a lot of specs but didn't really explain the general scenario. Let me try again.

In federated or web SSO protocols, you commonly have an end user doing something at a relying party site, what draft-ietf-tokbind-https calls the Token Consumer, which triggers the need for authentication. It might be the site directly responding to a request for protected resources or it might be the user selecting "log me on with [Google, Facebook, My IDP, etc.]". Usually the user is sent off to the Identity Provider (IDP), what draft-ietf-tokbind-https calls the Token Producer, via an HTTP 302 with a location of the appropriate protocol endpoint at the IDP.

HTTP/1.1 302 Found
Location: https://idp.com/oauth-authz?client_id=abc9er&response_type=code&scope=openid+profile&etc=etc

Sometimes, however, the parameters are large enough to hit browser URL length limitations or there's information in the parameters that you don't want floating around in query strings (because it ends up in HTTP logs or is more likely to leak out via referer or whatever). In such cases then, rather than using a 302, the Token Consumer will respond with a 200 and content where the parameters are encoded as HTML form values that are auto-submitted in the User Agent, and thus are transmitted via the HTTP POST method to the IDP, with the result parameters being encoded in the body using the application/x-www-form-urlencoded format. Something like this would be the rough equivalent of the 302 above but that results in the request being POSTed to the IDP:

  HTTP/1.1 200 OK
  Content-Type: text/html;charset=UTF-8
  Cache-Control: no-cache, no-store

  <html>
   <head><title>Sending you to your identity provider</title></head>
   <body onload="javascript:document.forms[0].submit()">
    <form method="post" action="https://idp.com/oauth-authz">
      <input type="hidden" name="client_id" value="abc9er"/>
      <input type="hidden" name="response_type" value="code"/>
      <input type="hidden" name="scope" value="openid profile"/>
      <input type="hidden" name="etc" value="etc"/>
    </form>
   </body>
  </html>

What I'm looking for is a way indicate to allow the referred_token_binding to be sent to the IDP in such a case.

Does that help explain?

@annevk
Copy link

annevk commented Jul 1, 2015

Yeah that helps, thanks. (No comments at the moment as to what would be better.)

@b---c
Copy link
Contributor Author

b---c commented Jul 1, 2015

So just to recap (maybe stating the obvious) - I was imagining the above auto-post would have the Include-Referer-Token-Binding-ID header in the response and that would instruct the browser to send the referred_token_binding in the POST to https://idp.com/oauth-authz which is at a host/domain that's different than the one (say https://rp.com/stuff) that served the content. So that'd be:

  HTTP/1.1 200 OK
  Content-Type: text/html;charset=UTF-8
  Cache-Control: no-cache, no-store
  Include-Referer-Token-Binding-ID: true

  <html>
   <head><title>Sending you to your identity provider</title></head>
   <body onload="javascript:document.forms[0].submit()">
    <form method="post" action="https://idp.com/oauth-authz">
      <input type="hidden" name="client_id" value="abc9er"/>
      <input type="hidden" name="response_type" value="code"/>
      <input type="hidden" name="scope" value="openid profile"/>
      <input type="hidden" name="etc" value="etc"/>
    </form>
   </body>
  </html>

Whereas @balfanz imagined that the indicator be directly on the <form> element itself. That would look more like:

  HTTP/1.1 200 OK
  Content-Type: text/html;charset=UTF-8
  Cache-Control: no-cache, no-store

  <html>
   <head><title>Sending you to your identity provider</title></head>
   <body onload="javascript:document.forms[0].submit()">
    <form method="post" action="https://idp.com/oauth-authz" include-referer-token-binding="true">
      <input type="hidden" name="client_id" value="abc9er"/>
      <input type="hidden" name="response_type" value="code"/>
      <input type="hidden" name="scope" value="openid profile"/>
      <input type="hidden" name="etc" value="etc"/>
    </form>
   </body>
  </html>

I don't have a preference between the two (or any other alternative that might come up). I'm just pushing to have the eventual solution allow for it somehow.

@ve7jtb
Copy link

ve7jtb commented Jul 1, 2015

We should really be having this discussion on the list:)

I think that the second option is probably more flexible.
It would make no difference for the simple use case of a authn request, however there may be cases where JS is loaded from a origin that may want to include it’s origin token binding for some calls and not others.

The header approach seems more like a all or nothing proposition.

Perhaps someone more familiar with proser based JS could give us a more informed opinion.

John B.

On Jul 1, 2015, at 11:30 AM, Brian Campbell [email protected] wrote:

So just to recap (maybe stating the obvious) - I was imagining the above auto-post would have the Include-Referer-Token-Binding-ID header in the response and that would instruct the browser to send the referred_token_binding in the POST to https://idp.com/oauth-authz https://idp.com/oauth-authz which is at a host/domain that's different than the one (say https://rp.com/stuff https://rp.com/stuff) that served the content. So that'd be:

HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Cache-Control: no-cache, no-store
Include-Referer-Token-Binding-ID: true

<title>Sending you to your identity provider</title> Whereas @balfanz https://github.com/balfanz imagined that the indicator be directly on the element itself. That would look more like:

HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Cache-Control: no-cache, no-store

<title>Sending you to your identity provider</title> I don't have a preference between the two (or any other alternative that might come up). I'm just pushing to have the eventual solution allow for it somehow.


Reply to this email directly or view it on GitHub #10 (comment).

@b---c
Copy link
Contributor Author

b---c commented May 13, 2016

At the meeting in Buenos Aires there seemed to be pretty wide consensus that the Include-Referer-Token-Binding-ID only having meaning for 30x status codes was sufficient for the scope of the draft-ietf-tokbind-https document. And that fetch() or other things that might use TB could define their own semantics for it if/when necessary.

As of draft -03 the Include-Referer-Token-Binding-ID header is defined to have meaning for 301, 302, 303, 307 or 308. So transmitting an authentication request to the token provider/IDP via the HTTP POST method could be achieved by the token consumer/RP sending an auto-submitting form post with the request back to itself and responding to that with a 307 directing the browser to resubmit the POST data to the token provider/IDP. It's a little ugly but will work with only the functionally provided by draft-ietf-tokbind-https.

So with all that said, I think what I'm trying to say here is that this issue can be closed now.

@annevk
Copy link

annevk commented May 16, 2016

FWIW, integration with https://fetch.spec.whatwg.org/ encompasses much more than fetch(). When done properly it'll define how this works with respect to navigation, <img>, service workers, various CSS features, <script>, fetch(), etc. It's basically the layer between client-side APIs and the network for browsers and software like browsers (e.g., spiders).

@balfanz
Copy link
Member

balfanz commented Jul 3, 2016

Closing this as per Brian's comment.

@balfanz balfanz closed this as completed Jul 3, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants