Subject: [OAUTH-WG] OAuth2 2 legged flows with JWT client assertions

From: George Fletcher <[email-masked]>
Date: Tue, 15 Sep 2015 14:09:57 -0400

Hi,

I just want to verify my reading of RFC 7523[1] for the use case where a 
client wants to get an access token for itself to use as authorization 
for future API calls. This is effectively exchanging a JWS for a "short 
lived" access token.

My understanding of section 2.2 of RFC 7523, is that the 
'client_assertion_type' and 'client_assertion' replace the default 
[OAuth2 (RFC 6749)] client authentication mechanism of client_id and 
client_secret.

Therefore the correct way to implement this 2 legged flow is to use the 
OAuth2 (RFC 6749) client_credentials grant_type (Section 4.4) with the 
JWT Bearer defined client_assertion_type and client_assertion.

This would look something like (line breaks added for readability)

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

grant_type=client_credentials&
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&
client_assertion=<encoded JWS>&
scope="myscopes"

Is there a different industry standard for this use case? I'm checking 
as I find that multiple AS implementations do this differently:) Thanks, 
George

[1] https://tools.ietf.org/html/rfc7523

---

From: Justin Richer <[email-masked]>
Date: Tue, 15 Sep 2015 16:41:58 -0400

That’s how we’ve implemented it, but I’ve seen others pass the JWS for the token directly using the assertion grant type. Personally I find that a little confusing, since it’s still the client making the swap, but maybe there’s something useful there anyway. It honestly feels a bit too much like WS-*, and one can hope that we’ve learned from the mistakes of the past by now.

I think the difference may be who makes the JWS. If the client is making the JWS and using it to swap for a new token, then that’s a case for using client credentials and authenticating using the JWS. If the JWS is coming from a third party and being handed to the client, and the client’s using that as-is to swap for a new token, then that’s a case of using the JWS as an assertion directly to the AS and getting a token there. 

But I agree that it’s confusing that there are two similar mechanisms here.

 — Justin

> On Sep 15, 2015, at 2:09 PM, George Fletcher <[email-masked]> wrote:
> 
> Hi,
> 
> I just want to verify my reading of RFC 7523[1] for the use case where a client wants to get an access token for itself to use as authorization for future API calls. This is effectively exchanging a JWS for a "short lived" access token.
> 
> My understanding of section 2.2 of RFC 7523, is that the 'client_assertion_type' and 'client_assertion' replace the default [OAuth2 (RFC 6749)] client authentication mechanism of client_id and client_secret.
> 
> Therefore the correct way to implement this 2 legged flow is to use the OAuth2 (RFC 6749) client_credentials grant_type (Section 4.4) with the JWT Bearer defined client_assertion_type and client_assertion.
> 
> Is there a different industry standard for this use case? I'm checking as I find that multiple AS implementations do this differently:)
> 
> Thanks,
> George
> [1] https://tools.ietf.org/html/rfc7523 <https://tools.ietf.org/html/rfc7523>
> _______________________________________________
> OAuth mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/oauth

---

From: Brian Campbell <[email-masked]>
Date: Wed, 16 Sep 2015 10:27:31 -0600

Yeah, when a client wants to get an access token for itself, the
client_credentials grant_type with client_assertion_type/client_assertion.

We attempted to call this out in the assertion framework (RFC 7521) in a
discussion of "Common Scenarios
<http://tools.ietf.org/html/rfc7521#section-6>" with the section "Client
Acting on Behalf of Itself <http://tools.ietf.org/html/rfc7521#section-6.2>"
but, despite good intentions, inheritance in specs is often overlooked.

   When a client is accessing resources on behalf of itself, it does so
   in a manner analogous to the Client Credentials Grant defined in
   Section 4.4 <http://tools.ietf.org/html/rfc7521#section-4.4> of
OAuth 2.0 [RFC6749 <http://tools.ietf.org/html/rfc6749>].  This is a
special case that
   combines both the authentication and authorization grant usage
   patterns.  In this case, the interactions with the authorization
   server should be treated as using an assertion for Client
   Authentication according to Section 4.2
<http://tools.ietf.org/html/rfc7521#section-4.2>, while using the
"grant_type"
   parameter with the value "client_credentials" to indicate that the
   client is requesting an access token using only its client
   credentials.

   The following example demonstrates an assertion being used for a
   client credentials access token request, as defined in Section
4.4.2 <http://tools.ietf.org/html/rfc7521#section-4.4.2>
   of OAuth 2.0 [RFC6749 <http://tools.ietf.org/html/rfc6749>] (with
extra line breaks for display purposes
   only):

     POST /token HTTP/1.1
     Host: server.example.com

     grant_type=client_credentials&
     client_assertion_type=urn%3Aietf%3Aparams%3Aoauth
     %3Aclient-assertion-type%3Asaml2-bearer&
     client_assertion=PHNhbW...[omitted for brevity]...ZT

On Tue, Sep 15, 2015 at 2:41 PM, Justin Richer <[email-masked]> wrote:

> That’s how we’ve implemented it, but I’ve seen others pass the JWS for the
> token directly using the assertion grant type. Personally I find that a
> little confusing, since it’s still the client making the swap, but maybe
> there’s something useful there anyway. It honestly feels a bit too much
> like WS-*, and one can hope that we’ve learned from the mistakes of the
> past by now.
>
> I think the difference may be who makes the JWS. If the client is making
> the JWS and using it to swap for a new token, then that’s a case for using
> client credentials and authenticating using the JWS. If the JWS is coming
> from a third party and being handed to the client, and the client’s using
> that as-is to swap for a new token, then that’s a case of using the JWS as
> an assertion directly to the AS and getting a token there.
>
> client wants to get an access token for itself to use as authorization for
> future API calls. This is effectively exchanging a JWS for a "short lived"
> access token.
>
> 'client_assertion_type' and 'client_assertion' replace the default [OAuth2
> (RFC 6749)] client authentication mechanism of client_id and client_secret.
>
> OAuth2 (RFC 6749) client_credentials grant_type (Section 4.4) with the JWT
> Bearer defined client_assertion_type and client_assertion.
>

---

From: George Fletcher <[email-masked]>
Date: Wed, 16 Sep 2015 16:33:06 -0400

Thanks for the pointer Brian, that's helpful! (and yes I didn't dig 
through the framework spec:)

On 9/16/15 12:27 PM, Brian Campbell wrote:
> We attempted to call this out in the assertion framework (RFC 7521) in 
> a discussion of "Common Scenarios 
> <http://tools.ietf.org/html/rfc7521#section-6>" with the section 
> "Client Acting on Behalf of Itself 
> <http://tools.ietf.org/html/rfc7521#section-6.2>" but, despite good 
> intentions, inheritance in specs is often overlooked.
>
>     Section 4.4 <http://tools.ietf.org/html/rfc7521#section-4.4>  of OAuth 2.0 [RFC6749 <http://tools.ietf.org/html/rfc6749>].  This is a special case that
>     Authentication according toSection 4.2 <http://tools.ietf.org/html/rfc7521#section-4.2>, while using the "grant_type"
>     client credentials access token request, as defined inSection 4.4.2 <http://tools.ietf.org/html/rfc7521#section-4.4.2>
>     of OAuth 2.0 [RFC6749 <http://tools.ietf.org/html/rfc6749>] (with extra line breaks for display purposes
>     only):
>
>       POST /token HTTP/1.1
>       Host:server.example.com <http://server.example.com>
> On Tue, Sep 15, 2015 at 2:41 PM, Justin Richer <[email-masked] 
> <mailto:[email-masked]>> wrote:
>
>     That’s how we’ve implemented it, but I’ve seen others pass the JWS
>     for the token directly using the assertion grant type. Personally
>     I find that a little confusing, since it’s still the client making
>     the swap, but maybe there’s something useful there anyway. It
>     honestly feels a bit too much like WS-*, and one can hope that
>     we’ve learned from the mistakes of the past by now.
>
>     I think the difference may be who makes the JWS. If the client is
>     making the JWS and using it to swap for a new token, then that’s a
>     case for using client credentials and authenticating using the
>     JWS. If the JWS is coming from a third party and being handed to
>     the client, and the client’s using that as-is to swap for a new
>     token, then that’s a case of using the JWS as an assertion
>     directly to the AS and getting a token there.
>
>>     On Sep 15, 2015, at 2:09 PM, George Fletcher <[email-masked]
>>     <mailto:[email-masked]>> wrote:
>>
>>     Hi,
>>
>>     I just want to verify my reading of RFC 7523[1] for the use case
>>     where a client wants to get an access token for itself to use as
>>     authorization for future API calls. This is effectively
>>     exchanging a JWS for a "short lived" access token.
>>
>>     'client_assertion_type' and 'client_assertion' replace the
>>     default [OAuth2 (RFC 6749)] client authentication mechanism of
>>     client_id and client_secret.
>>
>>     Therefore the correct way to implement this 2 legged flow is to
>>     use the OAuth2 (RFC 6749) client_credentials grant_type (Section
>>     4.4) with the JWT Bearer defined client_assertion_type and
>>     client_assertion.
>>
>>     Host: server.example.com <http://server.example.com>
>>     Is there a different industry standard for this use case? I'm
>>     checking as I find that multiple AS implementations do this
>>     differently:) Thanks, George
>>     [email-masked] <mailto:[email-masked]>
>     [email-masked] <mailto:[email-masked]>

-- 
George Fletcher <http://connect.me/gffletch>