Subject: [OAUTH-WG] Feedback on Device Flow draft 01

From: Oli Dagenais <[email-masked]>
Date: Wed, 13 Apr 2016 18:45:07 +0000

I am in the process of implementing Device Flow and, going by the specification draft at https://tools.ietf.org/html/draft-ietf-oauth-device-flow-01, have noticed some opportunities for improvement, which I am sharing and hoping to discuss.  I am new to providing feedback on IETF drafts, so if you would prefer my feedback be in another form (i.e. pull requests of suggested changes to the document source, creating tickets/issues in a work item tracker, posting to another mailing list, etc.), please let me know.

1.       Section 3.1 reads:

The client constructs a request URI by adding the following parameters to the request:

...it should read (since it's a POST request) like the first paragraph of section 4.1.3 in RFC6749 (although then we would need to add appendices - which makes sense if this is to become its own RFC):

   The client makes a request to the device endpoint by sending the
   following parameters using the "application/x-www-form-urlencoded"
   format per Appendix B<https://tools.ietf.org/html/rfc6749#appendix-B> with a character encoding of UTF-8 in the HTTP
   request entity-body:
2.       We may want to have Section 3.1 suggest (i.e. "RECOMMENDED") reasonable defaults for "expires_in" and "interval". It's probably reasonable to match the authorization code lifetime from section 4.1.2 of RFC6749 for expires_in:

"A maximum verification code lifetime of 600 seconds (10 minutes) is RECOMMENDED."

...alternatively, we write it like in section 4.2.2 of RFC6749:

   expires_in

         RECOMMENDED.  The lifetime in seconds of the verification code.

         For example, the value "600" denotes that the verification code

         will expire in ten minutes from the time the response was

         generated. If omitted, the authorization server SHOULD provide

         the expiration time via other means or document the default

         value.

As for "interval", the example in that section would lead us to believe 5 seconds is a reasonable default.  Again, we probably should flag it as RECOMMENDED to prevent too many clients from hammering the server, which will have to respond with "slow_down".
3.       Section 3.2 links to "Section 4.1.1 of RFC6749" but it seems to me it should link to section "4.1.3 of RFC6749" (Access Token Request).
4.       I recommend splitting section 3.1 (perhaps by using subsections) into "Authorization Request" and "Authorization Response".
5.       Section 3.2 is rather ambiguous as to the use of the token endpoint.  It might be useful to copy and adapt section 4.1.3 of RFC6749 to be explicit.  For example, is the "grant_type" supposed to be "authorization_code"?  I noticed the Azure Active Directory Library for .NET sets the grant_type to "device_code".  Something like:

grant_type
         REQUIRED.  Value MUST be set to "device_code".

code
         REQUIRED.  The device verification code received from the
         authorization server.

client_id
         REQUIRED, if the client is not authenticating with the
         authorization server as described in Section 3.2.1 of

         [RFC6749].

If the client type is confidential or the client was issued client
   credentials (or assigned other authentication requirements), the
   client MUST authenticate with the authorization server as described
   in Section 3.2.1 of [RFC6749].

For example, the client makes the following HTTPS request
   (with extra line breaks for display purposes only):

     POST /token HTTP/1.1
     Host: server.example.com
     Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
     Content-Type: application/x-www-form-urlencoded

     grant_type=device_code&code=74tq5miHKB

The authorization server MUST:

o  require client authentication for confidential clients or for any
      client that was issued client credentials (or with other
      authentication requirements),

o  authenticate the client if client authentication is included,

o  ensure that the verification code was issued to the authenticated
      confidential client, or if the client is public, ensure that the
      code was issued to "client_id" in the request, and

o  verify that the device verification code is valid.
6.       It seems like the device endpoint _could_ return an error (HTTP 400), under the following conditions:
a.       response_type is not "device_code"
b.       client_id is not recognized OR client did not otherwise authenticate appropriately
c.       scope isn't a value recognized by the implementation
d.       the method isn't POST (it appears Azure Active Directory supports GET and POST)
e.       Content-Type is not application/x-www-form-urlencoded
7.       Are there extra parameters that can be supplied to the device endpoint? What should happen to those?  Would they be passed through to the response?  If so, the documentation for the response should warn about extra parameters that MUST not break the client.
8.       In section 3.1, the device endpoint response example JSON reads:

"interval"=5

...it SHOULD read: (notice the '=' should have been ':')

"interval":5
9.       Section 3.3 reads:

   The following error responses are defined in addition to those within

   Section 4.2.2.1. of [RFC6749]:

...I think linking to Section 5.2 would be more appropriate, because 4.2.2.1 is about returning the response as parameters in the redirection URI whereas 5.2 is about responding with HTTP 400 and an application/json payload, which would make it more consistent with a successful device flow.  I see, however, that 4.2.2.1 includes "access_denied" and "server_error" error codes, so perhaps we must again cherry-pick from two sections to create new content that is unambiguous for the Device Flow specification.
10.   In Section 3.1, the type of "expires_in" and "interval" is not made explicit, although it is implied from the example.  Azure Active Directory returns them as JSON strings instead of JSON numbers.  We may want to replace:

   In response, the authorization server generates a verification code

   and an end-user code and includes them in the HTTP response body

   using the "application/json" format with a 200 status code (OK).  The

   response contains the following parameters:

...with something like:

   The authorization server generates a verification code and an

   end-user code, and constructs the response by adding the following

   parameters to the entity-body of the HTTP response with a 200 (OK)

   status code:

...and then add this between the last parameter and the example:

   The parameters are included in the entity-body of the HTTP response

   using the "application/json" media type as defined by [RFC4627].  The

   parameters are serialized into a JavaScript Object Notation (JSON)

   structure by adding each parameter at the highest structure level.

   Parameter names and string values are included as JSON strings.

   Numerical values are included as JSON numbers.  The order of

   parameters does not matter and can vary.

   The authorization server MUST include the HTTP "Cache-Control"

   response header field [RFC2616] with a value of "no-store" in any

   response containing tokens, credentials, or other sensitive

   information, as well as the "Pragma" response header field [RFC2616]

   with a value of "no-cache".

Cheers,
- Oli

--
Let me help you be awesome at what you do, using
Microsoft Developer Tools
+1 613-212-5551