Basic Auth for TargetEndpoint

Hello,

We have to call a target endpoint which needs username and password. We want to configure these credentials within Apigee, instead of getting them sourced from calling application.

Could you please advise, how this can be achieved.

Many Thanks!

1 5 153
5 REPLIES 5

Hello

Here, I had a similar need, and I solved it by:

  • Creating a KVM to store credentials, and adding keys and values
  • On my proxy, adding a KVM policy to retrieve these values
  • Adding a Python Script policy, to calculate the base64
  • Adding an Assign Message policy, to set header

The KVM policy:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<KeyValueMapOperations continueOnError="false" enabled="true" name="KV-Get-Credentials" mapIdentifier="KV-Authentication-Details">
  <DisplayName>KV-Get-Credentials</DisplayName>
  <Get assignTo="private.basicUsername" index="1">
    <Key>
      <Parameter>basicUsername</Parameter>
    </Key>
  </Get>
  <Get assignTo="private.basicPassword" index="1">
    <Key>
      <Parameter>basicPassword</Parameter>
    </Key>
  </Get>
  <Scope>environment</Scope>
</KeyValueMapOperations>

The Python script:

import base64
username = flow.getVariable("private.basicUsername")
password = flow.getVariable("private.basicPassword")
base64string = base64.encodestring('%s:%s' % (username, password))[:-1]
flow.setVariable("private.basicAuthN", base64string)

 The AssignMessage policy:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage continueOnError="false" enabled="true" name="AM-Set-BasicAuthN">
  <DisplayName>AM-Set-BasicAuthN</DisplayName>
  <Set>
    <Headers>
      <Header name="Authorization">Basic {private.basicAuthN}</Header>
    </Headers>
  </Set>
</AssignMessage>

 

Arnaduga

 

Many Thanks Arnaduga. I will try and confirm back!

And keep in mind there is a "BasicAuthentication" policy, which also will encode a basic auth header. Consider that an alternative to using the Python script for doing the encoding. And there's also an encodeBase64 static function available in the message template.

So, you have options

 

<BasicAuthentication name='BA-1'>
   <Operation>Encode</Operation>
   <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
   <User ref='private.username'/>
   <Password ref='private.password'/>
   <AssignTo>request.header.Authorization</AssignTo>
</BasicAuthentication>

 

or

 

<AssignMessage name='AM-Encode'>
  <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
  <AssignVariable>
    <Name>composite</Name>
    <Template>{private.username}:{private.password}</Template>
  </AssignVariable>
  <AssignVariable>
    <Name>encoded</Name>
    <Template>{encodeBase64(composite)}</Template>
  </AssignVariable>
</AssignMessage>

 

For a not-explainable reason, I was convinced the BasicAuthentication policy was for decoding only 😕

I prefer your option, Dino, definitely more elegant!

 

Thanks 

General comment:

With modern applications basic authentication is the least security preferred mechanism & would recommend to start adopting short lived JWT/JWS mechanism for better security posture.

https://docs.apigee.com/api-platform/reference/policies/jwt-policies-overview

If you still want to use (interim) basic authentication then you need to think about rotating the credentials on regular basis. Trying to shift the thinking on secure coding.