OpenID connect in Apigee Get user info Endpoint

Not applicable

Hello;

I have one problem with openID connect in apigee.

I read the tutorial of @Dino about how implement OpenId connect in apigee, and I made a successful call to get an

  • Id_token
  • Authorization_code,
  • Token

My Question is: When Client request an api with the Bearer token like this "access_token": "12rXuuGNdgd0GBz0DHOnXbceixTy"

How the API (backend) can get user info using this token, especially the “sub” attribute?

I really cannot figure out this piece of opened puzzle!

Thanks

Solved Solved
0 4 1,124
1 ACCEPTED SOLUTION

Hi - I'm glad you're checking out the Open ID Connect example.

It's possible you know this, but let's state it anyway just to make sure:

The Access Token is different than the ID Token.

The ID token is a JWT, and can be decoded and then digitally verified , with the right key. The JWT contains claims like "sub", "iss" and so on. This ID token is intended primarily for use by the client app. The IdP , which in this case is an API proxy bundle running in Apigee Edge, is issuing a signed token containing a set of assertions about the person or user. The client app can then rely on those assertions as being bonafide and valid.

The Access Token is different - it is intended to be retained by the client,but not interpreted or validated by the client. The client passes it to the API Gateway, which again in this case is Apigee Edge, when the client app makes requests on behalf of the user. The Access Token is an opaque string of characters. It cannot be decoded, except by the issuer (Apigee Edge). A client app presents it to the API provider (Apigee Edge) with a request and the provider can verify the token before allowing access to the APIs. The client app generally does not present the JWT (ID Token) to the API provider when requesting service.


ok, now that we have that bit out of the way. ...

I understand that you would like to allow the backend system, or even the API Proxy itself, to gain some knowledge of the user for which the access token was issued. You can do that with Apigee Edge.

We know that the client app is going to present the access token to Apigee Edge.

Every access token in Apigee Edge has associated to it, in the secure store, additional attributes. These attributes include: issued-at time, API Product name, expiry, and so on. Some of these are similaer to the claims you will find in an ID Token (JWT), but understand that these are distinct tokens, therefore they are distinct claims. To refer to the things associated to the opaque access token, I will sometimes use the term "metadata". As a person who controls the configuration of policies in Apigee Edge, you can tell Apigee Edge to attach custom attributes to the token, when it is issued. One example of a custom attribute you want to attach to a token might be "username".

The way to attach custom metadata to a token is using the Attributes element, like this:

 <OAuthV2 name="OAuthV2-GenerateAccessToken-AuthCode">
  <DisplayName>OAuthV2: Generate Access Token</DisplayName>
  <ExternalAuthorization>false</ExternalAuthorization>
  <Operation>GenerateAccessToken</Operation>
  <SupportedGrantTypes>
    <GrantType>authorization_code</GrantType>
  </SupportedGrantTypes>

    <!--
    Optional: these attributes get associated to the token.
    They will be made available to the api proxy via context variables, 
    when the token is subsequently validated.
    -->
    <Attributes>
      <Attribute name='username' ref='sub' display='false'/>
    </Attributes>

  <GenerateResponse />
</OAuthV2>

The 'sub' in the above refers to a context variable - something that is available within the request variable inside the Apigee Edge proxy. Context variables are ephemeral; they last only for the duration of the API request, which may last 10 milliseconds. But with this policy configuration, you are telling Apigee Edge "create a new token, and store an attribute called 'username' with it, and give that attribute the value of whatever is currently contained in the context variable called 'sub'."

You can read more about custom attributes in the Apigee docs.

When you configure the GenerateAccessToken policy this way, the generated token looks exactly the same. The client cannot tell that you have attached this metadata (the username) to the token. Instead what happens is, Apigee Edge stores in its token datastore, the random string that is the token, and the metadata, which in this case will include the username string.

And , when the client presents that token BACK to Apigee Edge when requesting service, Apigee Edge will READ the token store, retrieve all the metadata, and will be able to see "hey, this token was issued on behalf of username xxxxx".

It's up to you, the policy configuration person, to take some action based on the value of that custom attribute.

View solution in original post

4 REPLIES 4

Hi - I'm glad you're checking out the Open ID Connect example.

It's possible you know this, but let's state it anyway just to make sure:

The Access Token is different than the ID Token.

The ID token is a JWT, and can be decoded and then digitally verified , with the right key. The JWT contains claims like "sub", "iss" and so on. This ID token is intended primarily for use by the client app. The IdP , which in this case is an API proxy bundle running in Apigee Edge, is issuing a signed token containing a set of assertions about the person or user. The client app can then rely on those assertions as being bonafide and valid.

The Access Token is different - it is intended to be retained by the client,but not interpreted or validated by the client. The client passes it to the API Gateway, which again in this case is Apigee Edge, when the client app makes requests on behalf of the user. The Access Token is an opaque string of characters. It cannot be decoded, except by the issuer (Apigee Edge). A client app presents it to the API provider (Apigee Edge) with a request and the provider can verify the token before allowing access to the APIs. The client app generally does not present the JWT (ID Token) to the API provider when requesting service.


ok, now that we have that bit out of the way. ...

I understand that you would like to allow the backend system, or even the API Proxy itself, to gain some knowledge of the user for which the access token was issued. You can do that with Apigee Edge.

We know that the client app is going to present the access token to Apigee Edge.

Every access token in Apigee Edge has associated to it, in the secure store, additional attributes. These attributes include: issued-at time, API Product name, expiry, and so on. Some of these are similaer to the claims you will find in an ID Token (JWT), but understand that these are distinct tokens, therefore they are distinct claims. To refer to the things associated to the opaque access token, I will sometimes use the term "metadata". As a person who controls the configuration of policies in Apigee Edge, you can tell Apigee Edge to attach custom attributes to the token, when it is issued. One example of a custom attribute you want to attach to a token might be "username".

The way to attach custom metadata to a token is using the Attributes element, like this:

 <OAuthV2 name="OAuthV2-GenerateAccessToken-AuthCode">
  <DisplayName>OAuthV2: Generate Access Token</DisplayName>
  <ExternalAuthorization>false</ExternalAuthorization>
  <Operation>GenerateAccessToken</Operation>
  <SupportedGrantTypes>
    <GrantType>authorization_code</GrantType>
  </SupportedGrantTypes>

    <!--
    Optional: these attributes get associated to the token.
    They will be made available to the api proxy via context variables, 
    when the token is subsequently validated.
    -->
    <Attributes>
      <Attribute name='username' ref='sub' display='false'/>
    </Attributes>

  <GenerateResponse />
</OAuthV2>

The 'sub' in the above refers to a context variable - something that is available within the request variable inside the Apigee Edge proxy. Context variables are ephemeral; they last only for the duration of the API request, which may last 10 milliseconds. But with this policy configuration, you are telling Apigee Edge "create a new token, and store an attribute called 'username' with it, and give that attribute the value of whatever is currently contained in the context variable called 'sub'."

You can read more about custom attributes in the Apigee docs.

When you configure the GenerateAccessToken policy this way, the generated token looks exactly the same. The client cannot tell that you have attached this metadata (the username) to the token. Instead what happens is, Apigee Edge stores in its token datastore, the random string that is the token, and the metadata, which in this case will include the username string.

And , when the client presents that token BACK to Apigee Edge when requesting service, Apigee Edge will READ the token store, retrieve all the metadata, and will be able to see "hey, this token was issued on behalf of username xxxxx".

It's up to you, the policy configuration person, to take some action based on the value of that custom attribute.

Hello @Dino ... Thanks for the insightful answer. Would you be able to point me to a good doc or an article like this one, which talks about all kinds of tokens (access, id, bearer, pop etc...) and role they play?

Hi Vikash

Sorry, I don't have a good suggestion for you. The main token types I know of are:

  • access tokens
  • refresh tokens
  • ID tokens

Access tokens grant rights to service. They are generally Bearer tokens, indicating that the holder of the token will be granted service.

At the time a client requests a service, it presents the token. (in OAuthV2, this is done via the HTTP Authorization header, in the form 'Bearer TOKEN_GOES_HERE'. The service provider then extracts and validates the token, and if the token is valid, then the service provider provides the service. There may be service limits enforced - quotas or rate limits, etc.

Access tokens have a lifetime. After expiry, the access token will be rejected. At the time of issuing an access token, in some cases there is a companion refresh token issued, too. If there is a refresh token, then, when the access token has expired, the client can then make a special request for a new access token, using the refresh token. Subsequently the client then will have a new access token, with a new lifetime, and usually a new refresh token too.

OAuthV2 does not require tokens to be "Bearer" tokens. This opens the possibility that the token might represent a signature on the payload being sent. One such example of a proposal of non-Bearer tokens is the MAC token proposal. As the name "MAC" indicates, the idea here was that the token for each request would include a digital signature, a keyed message digest applied to some parts of the request.The MAC Token proposal has now expired as a suggested standard. I don't know why, but in any case, it was not adopted. So while so, OAuthV2 theoretically does not require Bearer tokens, as a practical matter I think today all standard OAuthV2 tokens are Bearer tokens.

The other type of token in my list is the ID token. And of course in OpenID Connect, the ID Token is a JWT (pronounced "jot").

JWT can be used for purposes other than ID tokens referring to a user. For example RFC 7523 describes how to use self-signed JWT to authenticate client applications.

Really, "token" is a very general term, which might be loosely defined as "string of characters". There are many different ways to use tokens, and depending on how you use them, the token will be generated and handled differently.

Thanks @Dino It was very helpful for me.