Search code examples
azureoauthadal

OAuth 2.0 Authorization Code Grant without secret


So I've been looking at setting up OAuth 2.0 for a Cordova mobile app using Microsofts cordova-plugin-ms-adal plugin (which uses the native libs) against a custom API using Azure AD. This all works well but I'm a bit confused with the use of the secret (or more specifically its absence).

In many articles on the web they state that when using the Authorization Code Grant and requesting a token, you include the secret. And that this grant type is ideal for use when you can securely store the secret e.g. on a server.

However the plugin does not require that a secret is specified in the app (and rightly so) but it still uses the Authorization Code Grant to authenticate. Also I can manually call

https://login.windows.net/common/oauth2/authorize?resource=http://***.onmicrosoft.com/***API&client_id=***&response_type=code&redirect_uri=http://***.onmicrosoft.com/***App

in my browser, login, get the code and then POST to https://login.windows.net/common/oauth2/token with

grant_type: authorization_code
client_id: ***
code: ***
redirect_uri: http://***.onmicrosoft.com/***App
resource: http://***.onmicrosoft.com/***API

and it works, so I get back a valid JWT, without having to send a secret.

Why!? Is this less secure? (I also noticed that the OAuth 2.0 spec section 4.1.3 does not state that the secret is required for grant type Authorization Code!?)

What are the implications of using a grant type of authorization_code without a secret / basic auth header?


Solution

  • The implication of using grant_type=authorization_code (or any other flow) with a public client (one that does not have a secret or authenticate in any other way) is that the access token granted does not represent an authorization of the client (the app) to directly access the resource, it represents an authorization for the client to access the resource on behalf of the user.

    This is why you'll notice in Azure AD Entra ID that when you register a native client app (a public client) you can only configure it to have delegated permissions to a resource, and not app-only permissions.