Can Client App skip verifying its client id before redirecting to login app in Auth Code grant type?

Hello,

About OAuth2 Authorization Code grant type, I have questions about the flow.

https://docs.apigee.com/api-platform/security/oauth/oauth-v2-policy-authorization-code-grant-type#fl...

From my perspective. I must create 3 endpoints in Apigee Edge

1. Authorize Endpoint (client app requests for verifying itself)

2. Generate Auth Code Endpoint (login app requests for generating auth code)

3. Generate Access Token Endpoint (client app uses auth code for requesting access token in behalf of end user)

#################

My Questions:

1. In the top of the flow, the first step is to validate client id's app. If it's successful, Edge will redirect to the login app, right?

a. What happen if client app ignores this step and starts with redirect to login app?

If it must has the client_id verification step, I can't imagine how to force.

If it's optional, how login app know who is the client_app.

b. What is the redirect_uri in this step? Does it mean "login app uri" or "client app callback uri" (same with 2b)?

#################

2. In the Generate Auth Code request,

a. What is the client_id in this step? Is it a client_key of "client app" or "login_app"?

--> After testing, I conclude that it's the client_key of client app, because it must be related with the requester in the next step (gen access token).

b. Is redirect_uri in this step a uri of client callback (for sending back auth code)?

Thank you.

Solved Solved
1 4 453
1 ACCEPTED SOLUTION

1. In the top of the flow, the first step is to validate client id's app. If it's successful, Edge will redirect to the login app, right?

Correct.

a. What happen if client app ignores this step and starts with redirect to login app?

Good question. In my implementations, I design the API Proxy to initiate an authorization "session", by populating a cache entry with some metadata about the client, and redirecting to the login endpoint with an identifier of that session. In practice it looks like this:

    <Flow name="authorize_app">
      <Condition>(proxy.pathsuffix MatchesPath "/authorize") and (request.verb = "GET")</Condition>
      <Description/>
      <Request>
        <Step><Name>OAuthV2-GetInfo</Name></Step>
        <Step><Name>AM-AuthorizationSession</Name></Step>
        <Step><Name>CP-AuthorizationSession</Name></Step>
      </Request>
      <Response>
        <Step>
          <!-- 
          The response is a 302 redirect to the login-and-consent app. 
          -->
          <Name>AM-RedirectToLoginApp</Name>
        </Step>
      </Response>
    </Flow>

You may be able to infer the purpose of the various policies. OauthV2-GetInfo is a GetOAuthV2Info policy, which retrieves information about the client (based on the client identifier). If the client id is invalid then this policy fails. AM-AuthorizationSession just creates a payload containing information about the client. CP-AuthorizationSession puts that payload into cache, using the messageid as the cache key. And finally AM-Redirect just sets the Location header pointing to the login endpoint, with the messageid as a queryparam.

Later, separately, the Login-and-consent app can call back into the Apigee Edge (on a session endpoint) to query information about the client. This might include: the client name, the developer name, the logo for the client app, and so on. (It's up to you).

b. What is the redirect_uri in this step? Does it mean "login app uri" or "client app callback uri" (same with 2b)?

The redirect_uri is registered per client. It can be verified by Apigee Edge, in this way: Using GetOAuthV2Info, Apigee Edge retrieves all of the registered metatdata for the client into context variables. At that point the proxy can check that the passed-in redirect_uri matches the registered redirect_uri. The redirect_uri is not actually *used* until the code is retrieved (a later step). It can be optionally validated here in this step, though.

Similarly, this step can also explicitly validate the set of scopes the client is requesting, too.

2. In the Generate Auth Code request, What is the client_id in this step? Is it a client_key of "client app" or "login_app"?

The client_id is for the registered client app. It is the same client_id as is passed to the /authorize endpoint.

b. Is redirect_uri in this step a uri of client callback (for sending back auth code)?

Yes.

I have a working example if you would like to examine it. Find it here. You should be able to just deploy it into your own organization and run it. There is a provisioning script that sets everything up, so it should be pretty easy. (and when you're finished, that script will tear everything down, too.)

As of now, the README now includes a sequence diagram showing the actors and how they all connect.

View solution in original post

4 REPLIES 4

1. In the top of the flow, the first step is to validate client id's app. If it's successful, Edge will redirect to the login app, right?

Correct.

a. What happen if client app ignores this step and starts with redirect to login app?

Good question. In my implementations, I design the API Proxy to initiate an authorization "session", by populating a cache entry with some metadata about the client, and redirecting to the login endpoint with an identifier of that session. In practice it looks like this:

    <Flow name="authorize_app">
      <Condition>(proxy.pathsuffix MatchesPath "/authorize") and (request.verb = "GET")</Condition>
      <Description/>
      <Request>
        <Step><Name>OAuthV2-GetInfo</Name></Step>
        <Step><Name>AM-AuthorizationSession</Name></Step>
        <Step><Name>CP-AuthorizationSession</Name></Step>
      </Request>
      <Response>
        <Step>
          <!-- 
          The response is a 302 redirect to the login-and-consent app. 
          -->
          <Name>AM-RedirectToLoginApp</Name>
        </Step>
      </Response>
    </Flow>

You may be able to infer the purpose of the various policies. OauthV2-GetInfo is a GetOAuthV2Info policy, which retrieves information about the client (based on the client identifier). If the client id is invalid then this policy fails. AM-AuthorizationSession just creates a payload containing information about the client. CP-AuthorizationSession puts that payload into cache, using the messageid as the cache key. And finally AM-Redirect just sets the Location header pointing to the login endpoint, with the messageid as a queryparam.

Later, separately, the Login-and-consent app can call back into the Apigee Edge (on a session endpoint) to query information about the client. This might include: the client name, the developer name, the logo for the client app, and so on. (It's up to you).

b. What is the redirect_uri in this step? Does it mean "login app uri" or "client app callback uri" (same with 2b)?

The redirect_uri is registered per client. It can be verified by Apigee Edge, in this way: Using GetOAuthV2Info, Apigee Edge retrieves all of the registered metatdata for the client into context variables. At that point the proxy can check that the passed-in redirect_uri matches the registered redirect_uri. The redirect_uri is not actually *used* until the code is retrieved (a later step). It can be optionally validated here in this step, though.

Similarly, this step can also explicitly validate the set of scopes the client is requesting, too.

2. In the Generate Auth Code request, What is the client_id in this step? Is it a client_key of "client app" or "login_app"?

The client_id is for the registered client app. It is the same client_id as is passed to the /authorize endpoint.

b. Is redirect_uri in this step a uri of client callback (for sending back auth code)?

Yes.

I have a working example if you would like to examine it. Find it here. You should be able to just deploy it into your own organization and run it. There is a provisioning script that sets everything up, so it should be pretty easy. (and when you're finished, that script will tear everything down, too.)

As of now, the README now includes a sequence diagram showing the actors and how they all connect.

Hi Dino,

Thank you very much. Your explanation and example are very clear and easy to follow.

After I complete implementing Auth Code Grant Type proxies, I review it and have another question.

from the flow https://docs.apigee.com/api-platform/images/oauth-auth-code-flow-(1).png

Let's say 3rd party client name is "ABC".

What actually is "Client App" who calls "/authorize"? Does it mean "A) ABC Application such as web app/mobile app" or "B) ABC Application Server"? or both can be.

From my point of view, when client app calls "/authorize" for verifying client, I think

  • If it's (A), the problem is client key located in HTML file and anyone can view ABC's client key in HTML source code.
  • If it's (B), the problem is ... when HTML login page return to ABC's server, it can attach some code or script before response to client application.

I think the other way should be:

  1. When user initiate the flow (by clicking button or something like that) on ABC's web application, it send the request to ABC's web server.
  2. ABC's web server requests "/authorize" to Apigee.
  3. If ABC is a validated app, Apigee returns HTTP status 200 with url of login app in payload (and some temporary session id). --> not 302 redirect
  4. ABC server sends redirect (302) back to ABC application.

-> This way can eliminate the problem in both (A) and (B).

Please suggest if there is another better solution.

Thank you.

Thanks for your question.

The client app calling the /authorize endpoint is the app that the user interacts with. This is typically a mobile app, a web app, or a deasktop app.

You are correct that if the client is a public client that runs via JAvaScript and HTML, it is not possible to store secrets in the client.

The OAuth2 recommended pattern then is to use Authorization Code grant type with PKCE to support public clients, and simply omit the use of the client secret.

It's important to realize that the OAuth2 framework does not imagine or require the client id to be a secret. The token grant can remain secure even if the client ID is knowable, as long as the rest of the constraints are followed, such as a fixed registered redirect URI and PKCE.


Also, please note that the current version of the security best practices document for OAuth from the OAuth working group recommends that apps avoid the Implicit grant type initially described in RFC 6749, in favor of a modified (no client secret) authorization code flow with PKCE.