Supporting OAuth "Public" clients in authorization code flow

Not applicable

According to OAuth2 spec, there are "Confidential" and "Public" clients, the difference is in that "Public" clients cannot store any secret safely (i.e. client_secret)

OpenId Connect spec, is based on OAuth2, so it follows the same Client Type distinction.

Now OpenId foundation has created a best practice implementation (SDK) for Android and iOS. So mobile Apps can use OpenID Connect to authenticate users.

These SDKs use the OAuth2 Authorization Code flow, however, since Mobile Apps are considered "Public" clients, the SDK makes the assumption that only the client_id is stored in the App.

So when the SDK tries to exchange the authorization_code for a access_token, the SDK does not authenticate using client_id AND client_secret.

So, here is the problem, in Apigee, the OAuth2 policy for GenerateAccessToken operation when using GrantType: authorization_code, requires authentication with client_id AND client_secret

Is there a way to modify this behavior?

Solved Solved
0 2 1,498
1 ACCEPTED SOLUTION

Roberto, good question.

There is not a way to modify the behavior of the GenerateAccessToken or GenerateAuthorizationCode policy. However, there may be a ready and easy workaround.

Given the client_id, you could design the API proxy flow to perform this sequence:

  1. VerifyApiKey to verify that the API key is valid
  2. AccessEntity to retrieve all the other metadata associated to the app, including the secret
  3. insert the id + secret into the appropriate header with a BasicAuthentication policy
  4. call the OAuthV2/GenerateAccessToken policy which will find the id + secret in the expected place

Does this make sense?

View solution in original post

2 REPLIES 2

This is a great question. I was researching this and I don't see a way to modify this behavior in the policy. I did notice a few things in the OAuth spec stating that it is up to the authorization server to determine how to authenticate a client. In this case, Apigee assumes that the client is "confidential," which is why we require the client ID and secret.

Roberto, good question.

There is not a way to modify the behavior of the GenerateAccessToken or GenerateAuthorizationCode policy. However, there may be a ready and easy workaround.

Given the client_id, you could design the API proxy flow to perform this sequence:

  1. VerifyApiKey to verify that the API key is valid
  2. AccessEntity to retrieve all the other metadata associated to the app, including the secret
  3. insert the id + secret into the appropriate header with a BasicAuthentication policy
  4. call the OAuthV2/GenerateAccessToken policy which will find the id + secret in the expected place

Does this make sense?