Best practice to pass Authorization token to target server when accessing the API through market pla

 

Hi

I have multiple target endpoints for the API proxy and the proxy is accessed through the API marketplace.

  Currently, passing the authorization token to the target end points through Authorization header (added the authorization token in Assign message headers and added assign message to the preflow for each target endpoint). Are there any best practices to pass the Authorization token to the target endpoint when the request is coming from an API consumer, instead of hard coding the token in Assign message? If so, can you please provide the steps with examples.

Could anyone please help with this @dino-at-google, @Former Community Member, @pietjacobs@dchiesa1.

Thank you in advance

0 9 602
9 REPLIES 9

Let's see if some of us can help out.  Can you elaborate on this statement?


@Shasi1 wrote:

Are there any best practices to pass the Authorization token to the target endpoint when the request is coming from an API consumer, instead of hard coding the token in Assign message?


I'm inferring that you're not comfortable "Hard-coding" things like tokens into an AssignMessage policy (Set/Headers/Header[@name=Authorization]) . And if that's what you're thinking, I don't blame you.  Normally a token is a short-lived thing, it's got a lifetime that is maybe 15 minutes, 30 minutes, or 60 minutes. Hard-coding what is, in essence, an ephemeral data item, is probably a bad idea. 

Another possibility is that you have a thing that you need to pass in the Authorization header, which you are calling a token, but which is not a typical token.  Maybe it's a long-lived thing, it has a lifetime that is 1 year or more.  So in this case it might be possible to consider that information to NOT be ephemeral data, which avoids the concern I described above. Even so, in this case we understand that the "token" is a secret.  It grants authorization to the backend (target), so it should be protected.  Which again means it should not be hard-coded. 

Is one or both of those issues, the source of your concern? 

If so, in the first case, I would suggest that you need to include some sort of token-management logic into the API Proxy, so that the proxy itself can periodically request and obtain a fresh token, which allows the proxy to invoke the target over many "epochs" of token lifetime. If you're clever, you can use the Apigee cache to store the token.  At runtime, the proxy can look in the cache, and if no token, or if the expiry of the token has elapsed, then you need to execute the "request new token" logic, and then store the new token into the cache. At that point, call AssignMessage to set the header, but use as the source of the Authorization header, the context variable that holds the token, whether retrieved from cache, or newly generated.

In the second case, I suggest storing the secret into the KVM, or into a proxy properties file. Which you choose depends on how secret the token is. then in the API Proxy at runtime, you need to use a KeyValueMapOperations policy to retrieve the data if you use KVM to store it. Or, if you use a property file, then the data is simply available in a context variable. 

Hi @dchiesa1 

Mine is the second case. I stored the secret in KVM I used KVM operations to retrieve the data and then assigned it to the Assign message. But the value is null when I run the trace. Can you please let me know what I am missing. Below is the sample code.

KVM Operation

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<KeyValueMapOperations async="false" continueOnError="false" enabled="true" name="Kvm" mapIdentifier="myidentifiervalue">
<DisplayName>kvm</DisplayName>
<Properties/>
<ExclusiveCache>false</ExclusiveCache>
<ExpiryTimeInSecs>300</ExpiryTimeInSecs>
<Get assignTo="token_value" index="1">
<Key>
<Parameter>kvm key value</Parameter>
</Key>
</Get>
<Scope>environment</Scope>
</KeyValueMapOperations>

Assign Message

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="Info">
<DisplayName>Info</DisplayName>
<Set>
<Headers>
<Header name="Authorization">{token_value}</Header>
</Headers>
<!-- <Verb>GET</Verb> -->
</Set>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="response"/>
</AssignMessage>

Hi dchiesa1,

can you please guide how to implement the first case a bit more. 

How did you load the value into the KVM? Via what mechanism?

Are you sure you are using the appropriate Parameter when retrieving the value?

What version of Apigee are you using?

If Edge, are you using an encrypted KVM? In that case you must use a variable with the prefix private. in the assignTo element.

Hi @dchiesa1 

using Apigee Edge. I haven't encrypted the KVM.

Yes, using the appropriate parameter when retrieving. I used the key.

Thanks

OK can you confirm that

  • myidentifiervalue is the name of your KVM Map?
  • And kvm key value (with spaces) is the name of the KVM key?

Maybe you should use a Key that does not have spaces. I don't recall ever having seen or tested that before. Have you tried a key with no spaces? eg something like this: 

<KeyValueMapOperations name='KVM-Get-1' mapIdentifier='nameOfMap'>
  <Scope>environment</Scope>
  <ExpiryTimeInSecs>300</ExpiryTimeInSecs>
  <Get assignTo='token_value'>
    <Key>
      <Parameter>param-with-no-spaces</Parameter>
    </Key>
   ...

If that doesn't solve it, can you show screenshots of

  • The KVM Admin UI, showing the KVM Map name, and the key name
  • the Trace, showing the "null value" for the "token_value" variable when the AssignMessage policy executes

Hi @dchiesa1 

The KVM value I just had one word and myidentifiervalue is the name of my kvpmap. Please see the below.

KVM

KVM.PNG

KVM Operations

KVMOperations.PNG

Assign Message

AssignMessage.PNG

Trace value

Trace.PNG

Please let me know if any additional details needed.

Thanks

Hmm ok that all looks good. 
are you certain that the KVM policy is executing? And is executing BEFORE the AssignMessage ? 

 

Hi @dchiesa1 

Actually, I am missing the KVM policy execution before the Assign message. I realized it a little while ago and now it is working fine.  Thank you so much for helping me on this.

I do have a follow question for this. Now, I am using encrypted KVM. I added private prefix to the name of the variable. As per the documentation "That prefix hides the value from Trace and debug sessions while you're debugging API proxies.".

 When I run the trace, I could see the message.header. Authorization value in the Assign message. Shouldn't the private key word hide the KVM value from entire trace?