Subject: [OAUTH-WG] OAuth 2.0 Mobile WebApp Flow

From: Nat Sakimura <[email-masked]>
Date: Wed, 26 May 2010 22:57:53 +0900

Back in February, I have suggested mobile web app flow to the oauth_wrap group.
Now that it is wrapped into OAuth 2.0, here is my another try, this
time for OAuth 2.0 draft.

"OAuth 2.0 Mobile WebApp Flow"
http://www.sakimura.org/en/modules/wordpress/oauth-20-mobile-webapp-flow/

I really wish that this could be included in OAuth 2.0 as it will help
build identity layers on OAuth 2.0 that works for mobile web browsers etc.

-- 
Nat Sakimura (=nat)
http://www.sakimura.org/en/
http://twitter.com/_nat_en

---

From: Marius Scurtescu <[email-masked]>
Date: Wed, 26 May 2010 10:54:14 -0700

Hi Nat,

The main use case for this flow would be for mobile apps that cannot
handle long URLs, is that correct? If so, I assume that the only
problematic long URL is the initial request sent through the
user-agent to the authorization server, right?

Does the Web Client run on the phone as well, or on some external web server?

Marius

On Wed, May 26, 2010 at 6:57 AM, Nat Sakimura <[email-masked]> wrote:
> _______________________________________________
> OAuth mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/oauth
>

---

From: "Manger, James H" <[email-masked]>
Date: Thu, 27 May 2010 12:07:13 +1000

Nat,

This looks like a decent idea: allow one user-uri parameter to reference a larger set of user-uri parameters held elsewhere -- to avoid URI size limits.

Hopefully it can be specified as another user-uri parameter -- not as a separate flow. It could be helpful for any of the delegation flows.

[I think the spec would be improved with a dedicated section on the user-uri (End-User endpoint) that lists all the parameters that it can take (that are defined in the spec) -- and explains each parameter (some will need their own sub-section). The per-flow sections would not repeat any of that: they could be a lot more succinct.]

Quick suggestion for text:

[for section 3.2 "End-user Endpoint"]
...
The following user-uri parameters are defined in this specification:
...
  inc_uri   A URI for obtaining further parameters for this request.

...
<inc_uri> allows parameters for the user-uri request to be referenced, instead of included directly. This is particularly helpful when the parameters are large and might not fit within the URI length limits of the user's browser. The response to a GET request to <inc_uri> SHALL be user-uri parameters in XXX format. Any parameter appearing directly in the user-uri SHALL override the same parameter obtained from <inc_uri>. The <inc_uri> response SHOULD be cacheable by including appropriate HTTP cache-control headers. The <inc_uri> SHALL be an HTTP or HTTPS URI, and SHOULD be the latter.

[Probably need a way for a service to indicate whether or not it supports <inc_uri>. Perhaps a "features=inc_uri,other" parameter in the HTTP WWW-Authenticate header.]

-- 
James Manger

---

From: David Recordon <[email-masked]>
Date: Wed, 26 May 2010 21:37:51 -0600

This feels exactly like the sort of thing that should be a new flow. Nat,
thanks for writing it up! I think the next step is getting it into the
XML2RFC format and some editing.

On Wed, May 26, 2010 at 8:07 PM, Manger, James H <
[email-masked]> wrote:

> Nat,
>
> This looks like a decent idea: allow one user-uri parameter to reference a
> larger set of user-uri parameters held elsewhere -- to avoid URI size
> limits.
>
> Hopefully it can be specified as another user-uri parameter -- not as a
> separate flow. It could be helpful for any of the delegation flows.
>
> [I think the spec would be improved with a dedicated section on the
> user-uri (End-User endpoint) that lists all the parameters that it can take
> (that are defined in the spec) -- and explains each parameter (some will
> need their own sub-section). The per-flow sections would not repeat any of
> that: they could be a lot more succinct.]
>
>
> <inc_uri> allows parameters for the user-uri request to be referenced,
> instead of included directly. This is particularly helpful when the
> parameters are large and might not fit within the URI length limits of the
> user's browser. The response to a GET request to <inc_uri> SHALL be user-uri
> parameters in XXX format. Any parameter appearing directly in the user-uri
> SHALL override the same parameter obtained from <inc_uri>. The <inc_uri>
> response SHOULD be cacheable by including appropriate HTTP cache-control
> headers. The <inc_uri> SHALL be an HTTP or HTTPS URI, and SHOULD be the
> latter.
>
>
> [Probably need a way for a service to indicate whether or not it supports
> <inc_uri>. Perhaps a "features=inc_uri,other" parameter in the HTTP
> WWW-Authenticate header.]
>
> --
> James Manger
>
>

---

From: "Manger, James H" <[email-masked]>
Date: Thu, 27 May 2010 14:13:41 +1000

David,

> This feels exactly like the sort of thing that should be a new flow.

Why is the size of the parameters related to the fundamental capabilities that distinguish flows (can/can't launch browser; can/can't receive redirects; can/can't keep client secret; is/isn't registered; with/without a user)?

Its not that some devices have URI limits and other don't. Its just that the size of the limits varies, which make the issue more pressing for selected mobile phones first. Perhaps there is no chance the ~2KB URI limit in IE will ever be exceeded -- but things like PAPE in OpenID strained similar assumptions there.

I guess I am just uncomfortable with the repetition between the flows.

--
James Manger

---

From: David Recordon <[email-masked]>
Date: Wed, 26 May 2010 22:23:17 -0600

Isn't the capability that distinguishes this flow the fact that URLs can not
be more than ~500 bytes?

On Wed, May 26, 2010 at 10:13 PM, Manger, James H <
[email-masked]> wrote:

> Why is the size of the parameters related to the fundamental capabilities
> that distinguish flows (can/can't launch browser; can/can't receive
> redirects; can/can't keep client secret; is/isn't registered; with/without a
> user)?
>
> Its not that some devices have URI limits and other don't. Its just that
> the size of the limits varies, which make the issue more pressing for
> selected mobile phones first. Perhaps there is no chance the ~2KB URI limit
> in IE will ever be exceeded -- but things like PAPE in OpenID strained
> similar assumptions there.
>

---

From: Nat Sakimura <[email-masked]>
Date: Thu, 27 May 2010 13:29:25 +0900

I can do the XML2RFC thing as well.

Shall I just make a section and upload the section somewhere?

=nat

On Thu, May 27, 2010 at 12:37 PM, David Recordon <[email-masked]> wrote:
> On Wed, May 26, 2010 at 8:07 PM, Manger, James H
> <[email-masked]> wrote:
>>
>> Nat,
>>

---

From: David Recordon <[email-masked]>
Date: Wed, 26 May 2010 22:37:19 -0600

I'd honestly write it as a standalone few page document. We really need to
show that flows can be defined outside of the core spec from an
extensibility standpoint.

On Wed, May 26, 2010 at 10:29 PM, Nat Sakimura <[email-masked]> wrote:

> >> From: [email-masked] [mailto:[email-masked]] On Behalf
> Of
> >> Nat Sakimura

---

From: David Recordon <[email-masked]>
Date: Wed, 26 May 2010 22:37:43 -0600

And have it become one of the official IETF Working Group documents though.

On Wed, May 26, 2010 at 10:37 PM, David Recordon <[email-masked]>wrote:

>> >> Back in February, I have suggested mobile web app flow to the
>> oauth_wrap
>> >> group.

---

From: Nat Sakimura <[email-masked]>
Date: Thu, 27 May 2010 13:41:19 +0900

That is the main reason I am pushing forward, but there are other
reasons as well.

For example, if the device is sitting on a slow network, it would be much
faster and thus user friendly if we move bulk of the payload server to server.

Another example of the merit is that when something like user identifiers are
to be sent to the end_user_endpoint, then it would be much better to
do it server to server than through the browser, which is a default
man-in-the-middle.

Implementation is going to be simpler as well. Since the request travels
server to server over SSL, it does not have to be signed to avoid tampering.
When these parameters are sent over browser redirect, they can be tampered.
To avoid the tampering, you need to sign the request, which is a big headache.

=nat

On Thu, May 27, 2010 at 1:23 PM, David Recordon <[email-masked]> wrote:
> On Wed, May 26, 2010 at 10:13 PM, Manger, James H

---

From: Nat Sakimura <[email-masked]>
Date: Thu, 27 May 2010 20:06:43 +0900

Just in case: I just took the existing oauth-2.0 draft xml and added
mobile web app flow.

Here is the XML snippet for the flow.

      <section anchor="mobile_web_app_flow" title="Mobile Web App Flow">
        <t>The moble web app flow is a user delegation flow suitable for
        clients capable of interacting with the end-user&rsquo;s user-agent
        (typically a web browser) that are capability constrained especially
        for url length and capable of receiving incoming requests from the
        authorization server (capable of acting as an HTTP server).</t>

        <t>The mobile web app flow includes following steps.</t>

        <t>
          <list style="format (%C)">
            <t>The web client creates a request file at a URL
            &ldquo;request_url&rdquo; that captures all the parameters that it
            would like to send to the Authorization Server including client
            identifier and a redirect URI to which the authorization server
            will send the end-user back once authorization is received (or
            denied).</t>

            <t>The web client initiates the flow by redirecting the
            end-user&rsquo;s user-agent to the end-user endpoint with
            request_url.</t>

            <t>The Authorization server obtains parameters by accessing
            request_url.</t>

            <t>The authorization server authenticates the end-user (via the
            user-agent) and establishes whether the end-user grants or denies
            the client&rsquo;s access request.</t>

            <t>Assuming the end-user granted access, the authorization server
            redirects the user-agent back to the client to the redirection URI
            provided earlier. The authorization includes a verification code
            for the client to use to obtain an access token.</t>

            <t>The client requests an access token from the authorization
            server by including its client credentials (identifier and
            secret), as well as the verification code received in the previous
            step.</t>

            <t>The authorization server validates the client credentials and
            the verification code and responds back with the access token.</t>
          </list>
        </t>

        <section title="Client Prepares a Request file at request_url">
          <t>Clients creates and saves the parameters in 3.6.1 at request_url.
          This file can be used many times, so it does not need to be done
          every time.</t>
        </section>

        <section title="Client Requests Authorization">
          <t>In order for the end-user to grant the client access, the client
          sends the end-user to the authorization server. The client
          constructs the request URI by adding the following URI query
          parameters to the end-user endpoint URI:<list hangIndent="6"
              style="hanging">
              <t hangText="type"><vspace /> REQUIRED. The parameter value MUST
              be set to <spanx style="verb">web_server</spanx>.</t>

              <t hangText="request_url"><vspace /> REQUIRED. Request file url
              from which the Authorization Server may obtain the request
              parameters. </t>

              <t hangText="immediate"><vspace /> OPTIONAL. The parameter value
              must be set to <spanx style="verb">true</spanx> or <spanx
              style="verb">false</spanx>. If set to <spanx
              style="verb">true</spanx>, the authorization server MUST NOT
              prompt the end-user to authenticate or approve access. Instead,
              the authorization server attempts to establish the end-user's
              identity via other means (e.g. browser cookies) and checks if
              the end-user has previously approved an identical access request
              by the same client and if that access grant is still active. If
              the authorization server does not support an immediate check or
              if it is unable to establish the end-user's identity or approval
              status, it MUST deny the request without prompting the end-user.
              Defaults to <spanx style="verb">false</spanx> if omitted.</t>
            </list></t>

          <t>The client directs the end-user to the constructed URI using an
          HTTP redirection response, or by other means available to it via the
          end- user&rsquo;s user-agent. The request MUST use the HTTP
          &ldquo;GET&rdquo; method. For example, the client directs the
          end-user&rsquo;s user-agent to make the following HTTPS requests
          (line breaks are for display purposes only):</t>

          <figure>
            <preamble>For example, the client directs the end-user's
            user-agent to make the following HTTPS requests (line breaks are
            for display purposes only):</preamble>

            <artwork><![CDATA[

  GET /authorize?type=web_server&client_id=s6BhdRkqt3&redirect_uri=
      https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
  Host: server.example.com

            ]]></artwork>
          </figure>

          <t>If the client has previously registered a redirection URI with
          the authorization server, the authorization server MUST verify that
          the redirection URI received matches the registered URI associated
          with the client identifier.</t>

          <t>The authorization server authenticates the end-user and obtains
          an authorization decision (by asking the end-user or establishing
          approval via other means). The authorization server sends the end-
          user&rsquo;s user-agent to the provided client redirection URI using
          an HTTP redirection response, or by other means available to it via
          the end-user&rsquo;s user-agent.</t>

          <section title="End-user Grants Authorization">
            <t>Refer to Section 3.6.1.1. </t>
          </section>

          <section title="End-user Denies Authorization">
            <t>Refer to Section 3.6.1.1. </t>

            <figure>
              <preamble>For example, the authorization server directs the
              client to make the following HTTP request:</preamble>
            </figure>

            <t>The authorization flow concludes unsuccessfully.</t>
          </section>
        </section>

        <section title="Client Requests Access Token">
          <t>The client obtains an access token from the authorization server
          by making an HTTP <spanx style="verb">POST</spanx> request to the
          token endpoint. The client constructs a request URI by adding the
          following parameters to the request: <list hangIndent="6"
              style="hanging">
              <t hangText="type"><vspace /> REQUIRED. The parameter value MUST
              be set to <spanx style="verb">web_server</spanx>.</t>

              <t hangText="client_id"><vspace /> REQUIRED. The client
              identifier as described in <xref target="client_id" />.</t>

              <t hangText="client_secret"><vspace /> REQUIRED if the client
              identifier has a matching secret. The client secret as described
              in <xref target="client_id" />.</t>

              <t hangText="code"><vspace /> REQUIRED. The verification code
              received from the authorization server.</t>
            </list></t>

          <t>The authorization server MUST verify that the verification code,
          client identity, client secret, and redirection URI are all valid
          and match its stored association. If the request is valid, the
          authorization server issues a successful response as described in
          <xref target="access_token_response" />.</t>

          <t>If the request is invalid, the authorization server returns an
          error response as described in <xref target="token_error" /> with
          one of the following error codes: <list style="symbols">
              <t>
                <spanx style="verb">redirect_uri_mismatch</spanx>
              </t>

              <t>
                <spanx style="verb">bad_verification_code</spanx>
              </t>

              <t>
                <spanx style="verb">incorrect_client_credentials</spanx>
              </t>
            </list></t>

          <figure>
            <preamble>For example:</preamble>

            <artwork><![CDATA[

  HTTP/1.1 400 Bad Request
  Content-Type: application/json
  Cache-Control: no-store

  {
    "error":"incorrect_client_credentials"
  }

            ]]></artwork>
          </figure>
        </section>
      </section>
    </section>

---

From: Marius Scurtescu <[email-masked]>
Date: Thu, 27 May 2010 10:10:45 -0700

Thanks for the clarification Nat.

Just curios, can't the phone client actually POST to the authz server?
That would take care of the URL length limitation.

In your diagram, the verification code is passed from UA to Web Client
and then the Web Client is exchanging it for the access and refresh
tokens. These tokens are never passed back to the UA, is that
intended? Also, why can't the UA do the exchange directly?

Marius

On Wed, May 26, 2010 at 6:11 PM, Nat Sakimura <[email-masked]> wrote:
> Yes. It is mainly for something called "feature phones" that has over
> 90% share in Japan.
>
> If it is the core OAuth only, it is not much of the problem.
> However, when we start adding something like Identity Layer on top of it,
> it starts to get problematic.
>
> The web client usually lives on external web server.
>
> Here are some answers to the question I got to the blog page from
> Luke, so that we can share them here as well.
>
> Q. Why "immediate" in the request?
>
> Initially, I was thinking like you did. Then, I got feedback from the
> community that if "immediate" was denied at the Authz Server, the RP
> may want to redo it with "immediate"=false, thus overriding what was
> written in the request file instead of making two versions of the
> request file. It is an override mechanism.
>
> Q. Why not "type" in the request?
>
> I could certainly include it in the request. Only the reason I did not
> was that it was already written in the request file, and it is not
> going to change like "immediate". The concern about having "type" in
> the request instead of request file is that it is easy to tamper.
> Since "type" is also used as some kind of security measure, it might
> be better to protect it if it is easy to do, and that was another
> reason for putting type in the request file and not request.
>
> Q. Name "rurl" confusing
>
> Originally, "rurl" was called "rpfurl" for Request Parameter File URL.
> Then, Breno told me that it is "mouthful" and since then it was
> wanting a better name. "rurl" was my attempt to make it not mouthful.
> Certainly, I can make it "request_url".
>
>
> On Thu, May 27, 2010 at 2:54 AM, Marius Scurtescu <[email-masked]> wrote:
>> Hi Nat,
>>

---

From: Nat Sakimura <[email-masked]>
Date: Fri, 28 May 2010 03:06:06 +0900

> That would take care of the URL length limitation.

POST means an extra click, which is a UI disaster.

Also, more data over the air means slower response.

> intended? Also, why can't the UA do the exchange directly?

It is following the Web Server flow.
Apart from getting the request parameter through the request_url fetch
is almost exactly as in the Web Server flow.

You could conceive similar things to UA-flow, I suppose.

---

From: Marius Scurtescu <[email-masked]>
Date: Thu, 27 May 2010 11:12:25 -0700

> POST means an extra click, which is a UI disaster.

I assume self posting forms do not work on these devices?

> Also, more data over the air means slower response.

True, but the alternative is to have the authz server fetch the data
from the web client, some cycles are lost there as well.

> is almost exactly as in the Web Server flow.

Sure, but who is the client in this case? Isn't the UA (aka phone)
ultimately interested in having access tokens so it can make API
calls?

Marius

---

From: Nat <[email-masked]>
Date: Fri, 28 May 2010 10:15:43 +0900

On 2010/05/28, at 3:12, Marius Scurtescu <[email-masked]> wrote:

>> On Fri, May 28, 2010 at 2:10 AM, Marius Scurtescu <[email-masked] 
>> > wrote:

Unfortunately, not.

> from the web client, some cycles are lost there as well.

The server to server connection generally is much faster.

> ultimately interested in having access tokens so it can make API

The UA on these devices are generally dumb. Generally speaking, we  
want the the web client to all the job and get only the summary to the  
UA.

---

From: "Manger, James H" <[email-masked]>
Date: Fri, 28 May 2010 14:12:22 +1000

Why are the 'type' and 'immediate' parameters provided directly (in the URI), instead of indirectly (in the response to the request_uri)?

The text implies all other parameters have to provided indirectly. Is there any criteria for choosing whether a parameter MUST, MAY or MUST NOT be provided indirectly? 

The example doesn't match the text as it directly include a 'client_id' parameter.

Allowing any parameters to be provided indirectly sounds more sensible.

-- 
James Manger

----------
From: Nat Sakimura [mailto:[email-masked]] 
Sent: Thursday, 27 May 2010 9:07 PM
To: David Recordon
Cc: Manger, James H; oauth
Subject: Re: [OAUTH-WG] OAuth 2.0 Mobile WebApp Flow

...
   Client Requests Authorization

       type         REQUIRED. The parameter value MUST be set to web_server

       request_url  REQUIRED. Request file url from which the Authorization
                              Server may obtain the request parameters 

       Immediate    OPTIONAL. The parameter value must be set to true or false... 
...

---

From: Nat Sakimura <[email-masked]>
Date: Sat, 29 May 2010 12:23:45 +0900

The "type" and "immediate" were the two parameters that I had
feedbacks that they want it in the URL. "type" being in the URL is
that implementations are using it as a switch. "immediate" was to
avoid creating two Request File in the case "immediate" did not
succeed. In my original manuscript, neither of them were there in the
URL.

As to the "example includes client_id in the URL" issue is concerned,
the example is wrong. I should remove the client_id from there.

All the request parameters MUST be provided through request file.
The "request_url" MUST be provided in the URL.
I am still not sure if "type" MUST be provided in the URL.
Conceptually, it need not be there. It depends on how implementors feel.
Any other parameters MAY be provided in the URL to override what is in
the request_file, but the URL total length MUST NOT exceed 512 bytes.

Would that be reasonable?

=nat

---

From: "Manger, James H" <[email-masked]>
Date: Mon, 31 May 2010 11:17:19 +1000

Nat,

> All the request parameters MUST be provided through request file.

"All" doesn't make much sense if params can still appear in the URI, and override the file.

> The "request_url" MUST be provided in the URL.

This isn't really a "MUST", its just indicates if you are using this feature (this "flow").

Would be good to say "A request_url param MUST NOT be provided in a request file". Probably good to add "A request file MUST be rejected if it includes a request_url param".

> Any other parameters MAY be provided in the URL to override what is in the request_file,

I agree.

> but the URL total length MUST NOT exceed 512 bytes.

That is reasonable.

--
James Manger