OAI / OpenAPI-Specification

The OpenAPI Specification Repository
https://openapis.org
Apache License 2.0
29.01k stars 9.07k forks source link

JWT-grant as a new Oauth2 flow #1875

Open joergenb opened 5 years ago

joergenb commented 5 years ago

RFC7523 extends Oauth2 by using JWTs as grants.

It would be nice if this behaviour could be added as a new type of flow under the Oauth2 securityScheme, in addition to existing ones (authorizationCode, implicit, etc.)

The full name in the RFC is urn:ietf:params:oauth:grant-type:jwt-bearer, but I guess JWT will suffice. Apart from that, the tokenUrl and scopes would be needed.

joergenb commented 5 years ago

https://github.com/OAI/OpenAPI-Specification/issues/1393 seems kinda related, but I think it should be possible to distinguish between using custom/proprietary JWTs compared to the standard-based approach above.

darrelmiller commented 5 years ago

Hey @joergenb thanks for raising this issue. As you can see we have been wrestling with how to deal with the notion of scopes outside of the OAuth2 flow and how they related to JWTs.

Whoa, I had never run into RFC7251 before and now my head hurts. Based on my intial understanding of what this is doing is it defines an extension mechanism to OAuth2 so that existing identity providers can invent their own grant_types and use those grant_types when making a token request. (Asusming the identity providers go off and write an extension based on 7251)

To date when talking about OAuth2 flows, that generally defines which grant_type is used when making the token request. RFC7251 basically ignores the notion of flows and says give me a grant_type and the corresponding assertion.

Having said that, this section https://tools.ietf.org/html/rfc7523#section-2.2 confuses me as it is using authorization_code as the grant_type.

I agree we need to add support for these additional grant_types. I just need to get a better grasp of how this all fits together to understand how it best fits into OAS.

/cc @MikeRalphson

shiup commented 4 years ago

In addition to JWT grant type, please also add SAML grant type.

And if possible, allow us to extend the definition, like x-jwt-grant, x-saml-grant, x-wicked-grant, for example.

johakoch commented 3 years ago

@darrelmiller

To date when talking about OAuth2 flows, that generally defines which grant_type is used when making the token request. RFC7251 basically ignores the notion of flows and says give me a grant_type and the corresponding assertion.

I don't understand your point. RFC 7251 is a framework defining how to use assertions as authorization grants (in addition to other grants like authorization code or client credentials as defined in RFC 6749). Additionally, these assertions can be used to authenticate a client (see below).

RFC 7523 defines JWT to be one specific kind of such an assertion.

Having said that, this section https://tools.ietf.org/html/rfc7523#section-2.2 confuses me as it is using authorization_code as the grant_type.

The example you cited is about using JWT to authenticate the client, not using it as a grant at the token endpoint. So this is an alternative to using Basic Auth or adding client_id and client_secret in the application/x-www-form-urlencoded message body.

I agree we need to add support for these additional grant_types. I just need to get a better grasp of how this all fits together to understand how it best fits into OAS.

Proposal:

components:
  securitySchemes:
    OAuthJB:
      type: oauth2
      flows:
        jwtBearer:
          tokenUrl: https://authorization-server.example.com/token
          scopes:
            read: Read a resource
    OAuthSB:
      type: oauth2
      flows:
        saml2Bearer:
          tokenUrl: https://authorization-server.example.com/token
          scopes:
            read: Read a resource
ioggstream commented 3 years ago

Any news on that?

ioggstream commented 2 years ago

@darrelmiller like @johakoch wrote, using JWTs for Client Authentication can already be expressed as such, though the OAS spec does not contain all the required information to retrieve the token. For example, we need to specity client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer and the JWT schema, in terms of the specific required claims/header-parameters.

Currently all those information are usually in description but it would be great to have a way to specify them.

    OAuth2:
      type: oauth2
      flows:
        clientCredentials:  # <- iiuc it's either  clientCredential or authorizationCode(PKCE)
          tokenUrl: https://pdnd.gov.it/as/token
          description: |-
            client_assertion_type: ...
            client_assertion format
          scopes:
            write:pets: modify pets in your account
            read:pets: read your pets

To support instead JWT as Authorization Grant, it is probably required to register new keywords.

SwapnilKhante commented 9 months ago

Hi Could you please share an example, I need to setup client_assertion and client_assertion_type with the oauth2 client credential flow so that I can use the authorize option in the swagger UI to fetch a token. Currently openapi documentation does not have an example, seems its not possible at the moment. This is the example https://backstage.forgerock.com/docs/am/7/oauth2-guide/client-auth-jwt.html

johakoch commented 9 months ago

@SwapnilKhante No, I guess, it's not possible at the moment.

Keep in mind that there is a difference between using jwt-bearer as grant (grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer, assertion=ey...) and using it as a client authentication mechanism (client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer, client_assertion=ey...).

johakoch commented 9 months ago

Using jwt-bearer as a client authentication mechanism would be an alternative to specifying (client_id and) client_secret in the Swagger UI. However, if you want to support this alternative, there should probably be a way to specify client authentication alternatives per OpenAPI.

In https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata there are e.g. token_endpoint_auth_methods_supported with values client_secret_post, client_secret_basic, client_secret_jwt, and private_key_jwt