Subject: Re: [OAUTH-WG] Is User Agent Profile Secure in OAuth 2.0?

From: Oleg Gryb <[email-masked]>
Date: Tue, 3 Aug 2010 20:56:23 -0700 (PDT)

> From: Brian Eaton <[email-masked]>
> HTTP/1.1 302 Moved  Temporarily
> Location:  http://www.thirdparty.com/rpc_relay.html#access_token=12345

> 
> rpc_relay.html  is highly cached in the browser, so instead of
> incurring hundreds of ms to  fetch a file, the data lands in the
> third-party.com javascript in under a  millisecond.

I see your point, but let me try to eliminate the call to rpc_relay.html at all. 
After all, the ultimate goal is not to receive an access token, but a resource 
protected by that token. If there are mistakes in the suggestion below, please 
let me know what they are.

Let us assume that the response contains this instead of the Location header:

<HTML>
<HEAD>
<script>
function process(token, url) {
   document.params.setAttribute("method", "POST");
   document.params.setAttribute("action", url);
  document.params.submit();
}
</script>
</HEAD>
<BODY 
onload="process(document.params.access_token.value,document.params.url.value)">
<form name="params"> 
<input type="hidden" name="access_token" value="12345"/>
<input type="hidden" name="url" 
value="http://resourceserver.com/protected_resource.html"/>
</form>
</BODY>
</HTML>

Access token will be sent directly to the service provider. There is no need to 
call rpc_relay.html. There is no need to call that complicated cross domain 
communication logic described at FB. There is no need to create cookies.

You can do Ajax as well:

<HTML>
<HEAD>
<script>

function process(token, url) {
  
  xmlhttp=new XMLHttpRequest();
  params ="access_token="+token+"&....";
  xmlhttp.open("POST", url, true);
  xmlhttp.onreadystatechange = ...
  xmlhttp.send(params);
}
</script>
</HEAD>
...

Is there anything wrong with either of these approaches?

---

From: Luke Shepard <[email-masked]>
Date: Wed, 4 Aug 2010 04:34:49 +0000

Hi Oleg,

If you want to send an access token directly to the server, we have the web server flow designed to do that. The JS redirect or Ajax call is just a more complicated way to send the token to the server. The user-agent flow is intended for use where the resource needs to be accessed directly from the client - either in Javascript, or a mobile or desktop application.

OAuth 2.0 merely codifies what is already standard industry practice - Facebook, Twitter, Google, OpenSocial, and others rely on this cross domain technique in order to transfer access tokens within a client-only context.

On Aug 3, 2010, at 8:56 PM, Oleg Gryb wrote:

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

---

From: Michael D Adams <[email-masked]>
Date: Tue, 3 Aug 2010 22:30:34 -0700

On Tue, Aug 3, 2010 at 8:56 PM, Oleg Gryb <[email-masked]> wrote:
> protected by that token.

The goal is to allow the user to delegate to thirdparty.com her
authorization for the protected resources on resourceserver.com.  If
thirdparty.com never gets the access token, thirdparty.com can never
do anything on behalf of the user.

Mike

---

From: Marius Scurtescu <[email-masked]>
Date: Wed, 4 Aug 2010 08:13:48 -0700

> If you want to send an access token directly to the server, we have the web server flow designed to do that. The JS redirect or Ajax call is just a more complicated way to send the token to the ser…

Nitpick: in most cases the user-agent flow gives the client only a
short lived access token, mobile or desktop apps most likely want a
long lived refresh token.

Marius

---

From: Oleg Gryb <[email-masked]>
Date: Wed, 4 Aug 2010 08:45:40 -0700 (PDT)

----- Original Message ----
> From: Michael D Adams <[email-masked]>
> If> thirdparty.com never gets the access token, thirdparty.com can never
thirdparty.com never gets the access token in the scenario that Brian has 
described, becuase fragment that was sent by a service provider in Location 
header is not going to travel to the thirdparty.com server.

---

From: Brian Eaton <[email-masked]>
Date: Wed, 4 Aug 2010 09:04:05 -0700

> header is not going to travel to the thirdparty.com server.

This is not quite true.

thirdparty.com has a client-side and a server-side component.  The
thirdparty.com client-side component gets the access token and can use
it immediately.

The client-side component can then pass it up to the server-side
component, if the token is useful there.

---

From: Oleg Gryb <[email-masked]>
Date: Wed, 4 Aug 2010 09:27:09 -0700 (PDT)

----- Original Message ----
> From: Luke Shepard <[email-masked]>
> If you want to send an access token directly to the server, we  have the web 
>server flow designed to do that. The JS redirect or Ajax call is  just a more 
>complicated way to send the token to the server. The user-agent flow  is 
>intended for use where the resource needs to be accessed directly from the  
>client - either in Javascript, or a mobile or desktop application.
> 

We're not discussing web server profile here and my objective is not to send an 
"access token directly to the server", but to eliminate secrets in URL.  

> OAuth  2.0 merely codifies what is already standard industry practice - 
>Facebook,  Twitter, Google, OpenSocial, and others rely on this cross domain 
>technique in  order to transfer access tokens within a client-only context.
> 

I would not mix the existing implementation and the standard. Standard could and 
should be more generic. The wording around UA flow is generic enough, but it has 
one implementation specific feature - sending access token in a URL's fragment. 
I don't understand why it should be there. I think nobody will argue, if I say 
that there are other ways of transferring access tokens between parties 
involved. I've even provided one example where URL's fragment is not used. I 
didn't hear yet why it wouldn't work. I might have missed some important steps 
in that example, but I think, if mistakes or omissions do exist, they can be 
easily fixed by adding extra steps and probably even extra round trips to a 
third party server (sorry, Brian).

Here is my final proposal in regards of UA profile.

Let me try to re-write steps C to E in a way that will not break the existing 
implementations, but at the same time will leave some room for other 
implementations:

   (C) If the end-user granted access, the authorization server
         will issue an access token and pass it to the user agent.

   (D) The user-agent will use the access token granted by the 
        authorization server to get access to a protected resource 
        on the resource server.

---

From: Oleg Gryb <[email-masked]>
Date: Wed, 4 Aug 2010 09:42:18 -0700 (PDT)

> To: Oleg Gryb <[email-masked]>
> Cc: Michael D Adams <[email-masked]>; [email-masked]
> Sent: Wed, August 4, 2010 9:04:05 AM
> Subject: Re: [OAUTH-WG] Is User Agent Profile Secure in OAuth 2.0?
> 

I don't see the secret sharing logic (with thirdparty.com server) in your 
example or even in UA flow spec.
Everything looks like immediate redirects so far. Would you need to make an 
extra trip to the server for that?

Please provide an example, then I'll try to change my example as well (to add 
secret sharing logic).

---

From: Michael D Adams <[email-masked]>
Date: Wed, 4 Aug 2010 09:46:44 -0700

> header is not going to travel to the thirdparty.com server.

As Brian mentioned, the client-side component hosted on thirdparty.com
does get the access token in the User Agent flow.  That means the
client-side script can access multiple protected resources (upload a
photo, update the user's profile, flag the user as "online", download
a friends list, whatever) in the same page load.

If I'm interpreting your idea correctly, only one protected resource
can be accessed per access token since the thirdparty.com app never
sees the token.  For every resource it needs, thirdparty.com has to
send the user through the authorization server again.  Am I mistaken?

---

From: Oleg Gryb <[email-masked]>
Date: Wed, 4 Aug 2010 10:20:18 -0700 (PDT)

----- Original Message ----
> send the user  through the authorization server again.  Am I  mistaken?

in my example, after:

you can add:
document.cookie="access_token=...

Theoretically, it'll create a cookie in the resource server domain (I'm saying 
theoretically, becuase didn't test it). Next time when UA goes to the same 
resource server, the latter can use the cookie to do authentication. It means 
that you don't need to go to authz server again until token is expired.

If this is correct, why would you need to share the secret with thirdparty.com 
server? It actually makes the solution more secure, if you don't, becuase access 
token is known to UA only.

In my Ajax example you don't even need a cookie, becuase access_token can be 
stored in a JavaScript variable.

---

From: Michael D Adams <[email-masked]>
Date: Wed, 4 Aug 2010 10:55:08 -0700

> that you don't need to go to authz server again until token is expired.

I thought that page in your idea was being served from the
Authorization Server (not the Resource Server). If that's true, the
cookie would be on the wrong domain.

Mike

---

From: Oleg Gryb <[email-masked]>
Date: Wed, 4 Aug 2010 11:07:46 -0700 (PDT)

----- Original Message ----

> cookie would be on the wrong  domain.

It might be a problem if resource and authz servers are in different domains, 
but in all discussions with Brian we used that "service provider" term and I've 
assumed that service provider acts like authz server and resource server or at 
least latter two are in the same domain. 

I think it's a common scenario for web apps when authentication logic resides on 
the same web server where protected resources are.

It's not the major point though. The hypothesis that I'm trying to prove is that 
access token doesn't need to be transferred in a URL.