How to add username Developers to target api header through api proxy

I want get username of developers  after verify apikey success and add it to target api header through api proxy, because my backend service need username of user request. How can resolve that? Thanks

Example:

User1 call api proxy 1 verify by apikey, if success -> proxy add value "user1" to header of target api.

 

Solved Solved
0 10 423
4 ACCEPTED SOLUTIONS

Sure thing. According to the documentation for the VerifyAPIKey policy, context variables populated by the VerifyAPIKey policy, include

variable name description
verifyapikey.{policy_name}.client_id The consumer key (aka API key or app key) supplied by the requesting app
verifyapikey.{policy_name}.client_secret The consumer secret associated with the consumer key
verifyapikey.{policy_name}.developer.app.id the id of the developer app
verifyapikey.{policy_name}.developer.app.name The name of the developer app making the request
verifyapikey.{policy_name}.developer.id The ID of the developer registered as the owner of the requesting app
verifyapikey.{policy_name}.developer.email The email of the developer registered as the owner of the requesting app

So, if you wanted to inject a header containing the developer ID, then your request flow would be something like this:

 

<Step> 
  <Name>VerifyAPIKey-1</Name> 
</Step>
<Step> 
  <Name>AM-Inject-Developer-Email-Header</Name> 
</Step>

 

And if the verifyapikey policy name is VerifyAPIKey-1 , then the AssignMessage policy would be like this:

 

<AssignMessage name='AM-Inject-Developer-Email-Header'>
  <Set>
    <Headers>
      <Header name='Developer-Email'>{verifyapikey.VerifyAPIKey-1.developer.email}</Header>
    </Headers>
  </Set>
</AssignMessage>

 

View solution in original post

And I confirm the @dchiesa1 solution: I implemented exactly that in a "mandatory" sharedflow:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage continueOnError="false" enabled="true" name="AM-Prepare-backend-keys">
  <DisplayName>AM-Prepare-backend-keys</DisplayName>
  <Remove>
    <Headers>
      <Header name="x-api-key"/>
    </Headers>
  </Remove>
  <Set>
    <Headers>
      <Header name="x-dev-app">{verifyapikey.VK-Verify-APIkey.developer.app.name}</Header>
      <Header name="x-dev-app-id">{verifyapikey.VK-Verify-APIkey.developer.app.id}</Header>
      <Header name="x-dev-email">{verifyapikey.VK-Verify-APIkey.developer.email}</Header>
    </Headers>
  </Set>
  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</AssignMessage>

 

View solution in original post

I did a quick test, and I never used it on real production environment, but that could give partial answers.

 

I set a proxy, with one method/path acessible POST /token

In it, I added a single policy, OAuthV2, set as in the documentation (I focused my tests on client_credentials grant flow):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<OAuthV2 name="GetAccessToken">
  <Operation>GenerateAccessToken</Operation>
  <ExpiresIn>3600000</ExpiresIn>
  <SupportedGrantTypes>
    <GrantType>client_credentials</GrantType>
  </SupportedGrantTypes>
  <GenerateResponse/>
</OAuthV2>

Then, after deployment, assignment to an API Product, etc..., I made the following API call to retrieve a token:

$ curl --location --request POST 'https://<apiCustomDomain>/dev-oauth-tests/token' \
--header 'Authorization: Basic <base64(client_id:client_secret)>' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials'

Where client_id and client_secret are the one from my authorized applications (client_id can be used as APIKey as well)

And I got this answer:

{
    "refresh_token_expires_in": "0",
    "api_product_list": "[MyProduct]",
    "api_product_list_json": [
        "MyProduct"
    ],
    "organization_name": "ApigeeXOrg",
    "developer.email": "anEmail@company.com",
    "token_type": "BearerToken",
    "issued_at": "1659703309612",
    "client_id": "r...s",
    "access_token": "NAtoJukq4HiIYtu4Osxm4ATBjhbs",
    "application_name": "4706f971-9de8-4fea-8be4-6457f2047da7",
    "scope": "",
    "expires_in": "3599",
    "refresh_count": "0",
    "status": "approved"
}

 

So, I was able to use this token on another endpoint where you have to:

- Verify the access_token, with the OAUthV2 policy:

<OAuthV2 async="false" continueOnError="false" enabled="true" name="OAuth-v20-2">
    <DisplayName>OAuth v2.0 2</DisplayName>
    <Operation>VerifyAccessToken</Operation>
    <AccessTokenPrefix>Bearer</AccessTokenPrefix>
</OAuthV2>

- Get info from the TOKEN (introspect?), thanks the GetOAuthV2Info policy :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<GetOAuthV2Info continueOnError="false" enabled="true" name="Get-OAuth2-Info">
  <DisplayName>Get-OAuth2-Info</DisplayName>
  <AccessToken>{extractedAccessToken}</AccessToken>
</GetOAuthV2Info>

And then, do whatever you want with the result variables, like an AssignMessage:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage continueOnError="false" enabled="true" name="AM-Set-Dev-Email">
  <DisplayName>AM-Set-Dev-Email</DisplayName>
  <Set>
    <Headers>
      <Header name="x-dev-email">{apigee.developer.email}</Header>
    </Headers>
  </Set>
  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</AssignMessage>

Arnaduga_0-1659704975446.png

Again, not used in real environment, just a POC. I would need to go deeper, on JWT token for instance, etc... but, that's a start!

Arnaduga

 

 

View solution in original post

After an OAuthV2/VerifyAccessToken, the variables set will be: 

organization_name
developer.id
developer.email
developer.app.name
client_id
grant_type
token_type
access_token
accesstoken.{custom_attribute}
issued_at
expires_in
status
scope
apiproduct.name*
apiproduct.{custom_attribute_name}*
app.{custom-attribute-name}*

So I believe you just need

<AssignMessage name='AM-Inject-Developer-Email-Header'>
  <Set>
    <Headers>
      <Header name='Developer-Email'>{developer.email}</Header>
    </Headers>
  </Set>
</AssignMessage>

 

View solution in original post

10 REPLIES 10

Anyone know resolve this issues???

Sure thing. According to the documentation for the VerifyAPIKey policy, context variables populated by the VerifyAPIKey policy, include

variable name description
verifyapikey.{policy_name}.client_id The consumer key (aka API key or app key) supplied by the requesting app
verifyapikey.{policy_name}.client_secret The consumer secret associated with the consumer key
verifyapikey.{policy_name}.developer.app.id the id of the developer app
verifyapikey.{policy_name}.developer.app.name The name of the developer app making the request
verifyapikey.{policy_name}.developer.id The ID of the developer registered as the owner of the requesting app
verifyapikey.{policy_name}.developer.email The email of the developer registered as the owner of the requesting app

So, if you wanted to inject a header containing the developer ID, then your request flow would be something like this:

 

<Step> 
  <Name>VerifyAPIKey-1</Name> 
</Step>
<Step> 
  <Name>AM-Inject-Developer-Email-Header</Name> 
</Step>

 

And if the verifyapikey policy name is VerifyAPIKey-1 , then the AssignMessage policy would be like this:

 

<AssignMessage name='AM-Inject-Developer-Email-Header'>
  <Set>
    <Headers>
      <Header name='Developer-Email'>{verifyapikey.VerifyAPIKey-1.developer.email}</Header>
    </Headers>
  </Set>
</AssignMessage>

 

Thanks, i got it.

Now i want get user name of developer through OAuthV2 policy, how to extract that variables to assign message policy

After an OAuthV2/VerifyAccessToken, the variables set will be: 

organization_name
developer.id
developer.email
developer.app.name
client_id
grant_type
token_type
access_token
accesstoken.{custom_attribute}
issued_at
expires_in
status
scope
apiproduct.name*
apiproduct.{custom_attribute_name}*
app.{custom-attribute-name}*

So I believe you just need

<AssignMessage name='AM-Inject-Developer-Email-Header'>
  <Set>
    <Headers>
      <Header name='Developer-Email'>{developer.email}</Header>
    </Headers>
  </Set>
</AssignMessage>

 

Thanks for your support, i got it !!

@dchiesa1thanks for your support, i will try it 🙂

And I confirm the @dchiesa1 solution: I implemented exactly that in a "mandatory" sharedflow:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage continueOnError="false" enabled="true" name="AM-Prepare-backend-keys">
  <DisplayName>AM-Prepare-backend-keys</DisplayName>
  <Remove>
    <Headers>
      <Header name="x-api-key"/>
    </Headers>
  </Remove>
  <Set>
    <Headers>
      <Header name="x-dev-app">{verifyapikey.VK-Verify-APIkey.developer.app.name}</Header>
      <Header name="x-dev-app-id">{verifyapikey.VK-Verify-APIkey.developer.app.id}</Header>
      <Header name="x-dev-email">{verifyapikey.VK-Verify-APIkey.developer.email}</Header>
    </Headers>
  </Set>
  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</AssignMessage>

 

Thanks. Do you know get user name of developer through OAuthV2 policy ?

I did a quick test, and I never used it on real production environment, but that could give partial answers.

 

I set a proxy, with one method/path acessible POST /token

In it, I added a single policy, OAuthV2, set as in the documentation (I focused my tests on client_credentials grant flow):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<OAuthV2 name="GetAccessToken">
  <Operation>GenerateAccessToken</Operation>
  <ExpiresIn>3600000</ExpiresIn>
  <SupportedGrantTypes>
    <GrantType>client_credentials</GrantType>
  </SupportedGrantTypes>
  <GenerateResponse/>
</OAuthV2>

Then, after deployment, assignment to an API Product, etc..., I made the following API call to retrieve a token:

$ curl --location --request POST 'https://<apiCustomDomain>/dev-oauth-tests/token' \
--header 'Authorization: Basic <base64(client_id:client_secret)>' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials'

Where client_id and client_secret are the one from my authorized applications (client_id can be used as APIKey as well)

And I got this answer:

{
    "refresh_token_expires_in": "0",
    "api_product_list": "[MyProduct]",
    "api_product_list_json": [
        "MyProduct"
    ],
    "organization_name": "ApigeeXOrg",
    "developer.email": "anEmail@company.com",
    "token_type": "BearerToken",
    "issued_at": "1659703309612",
    "client_id": "r...s",
    "access_token": "NAtoJukq4HiIYtu4Osxm4ATBjhbs",
    "application_name": "4706f971-9de8-4fea-8be4-6457f2047da7",
    "scope": "",
    "expires_in": "3599",
    "refresh_count": "0",
    "status": "approved"
}

 

So, I was able to use this token on another endpoint where you have to:

- Verify the access_token, with the OAUthV2 policy:

<OAuthV2 async="false" continueOnError="false" enabled="true" name="OAuth-v20-2">
    <DisplayName>OAuth v2.0 2</DisplayName>
    <Operation>VerifyAccessToken</Operation>
    <AccessTokenPrefix>Bearer</AccessTokenPrefix>
</OAuthV2>

- Get info from the TOKEN (introspect?), thanks the GetOAuthV2Info policy :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<GetOAuthV2Info continueOnError="false" enabled="true" name="Get-OAuth2-Info">
  <DisplayName>Get-OAuth2-Info</DisplayName>
  <AccessToken>{extractedAccessToken}</AccessToken>
</GetOAuthV2Info>

And then, do whatever you want with the result variables, like an AssignMessage:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage continueOnError="false" enabled="true" name="AM-Set-Dev-Email">
  <DisplayName>AM-Set-Dev-Email</DisplayName>
  <Set>
    <Headers>
      <Header name="x-dev-email">{apigee.developer.email}</Header>
    </Headers>
  </Set>
  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</AssignMessage>

Arnaduga_0-1659704975446.png

Again, not used in real environment, just a POC. I would need to go deeper, on JWT token for instance, etc... but, that's a start!

Arnaduga

 

 

thank you very much !!