The OAuth2 specifications define six different grant types (https://tools.ietf.org/html/rfc6749 and https://tools.ietf.org/html/draft-ietf-oauth-device-flow-15). Each provides the most optimal (from the security point of view) way of obtaining access or (for OIDC) id_tokens given the circumstances of the client application. This blog summarizes the questions that the implementer of the OAuth2 client application needs to ask and how the answers lead to the selection of the appropriate grant.
There are two main questions and several variants on answers to them:
- Is there a user involved in the transaction or is this an un-attended client (e.g. a nightly batch run)? If a user is involved either directly interacting with the client or interacting with some other client, which called this application go to #2 below. Otherwise, the only applicable grant is the Client Credentials flow (see exception below). Note that the client app must be a confidential client (see https://tools.ietf.org/html/rfc6749#section-2.1).
- If a user is involved, the question to ask is whether the authorization server can use the browser interface to authenticate the user and obtain consent, if needed. There are several possible answers:
- Yes, browser can used immediately: this is a web app or a native app, which is able to open control hosting a browser. Use Authorization Code Grant. If this is a native app (public client), use PKCE extensions to the grant.
- Yes, browser is available BUT the authorization server cannot take control of it because my code is running in it, e.g. Single Page Application. Use Implicit Flow Grant. (There is a draft proposal to replace this grant type with Authorization Code/PKCE grant. However, most toolkits and many authorization servers do not yet fully support it when used from the browser so at this stage aware of potential change and limitations of Implicit Grant, which lead to these proposals).
- No, browser surface is not available to the app but some UI interaction with the user is possible, e.g. the application is running on a device which does not support browser interaction (a thermostat wall device or TV screen with no keyboard input). Use Device Code grant.
- No, browser surface is not available and user interaction is not needed because the application already has a token for this user – the application is an API in a multi-tier system, it was called with a token obtained using one of the other grants listed under #2 and now needs to call yet another API. Use the Extension Grant.
There is one other grant defined in the above spec: the Resource Owner Password grant. The only valid use for it is in clients which need a token representing a user but there is no user present when they execute. One example is a nightly batch run doing some Calendar operations for Office 365 delegated users. O365 may require that it be called with a token representing a user rather than application as would be the case if the Client Credentials flow was used (#1 above). Another example is un-attended web application testing. The application needs a user token but since a user is not present at execution it may use the ROP grant to create one and inject it into the test. ROP is inherently insecure, requires hard-coding of passwords, does not support MFA, etc. so it should never be used except for very narrow, specialized scenarios like the two above.