Configured username and password in the key value pairs
And get the user name and password by using the following policies
getUsername: this is used to get the username from the key value pairs.
<KeyValueMapOperations name="getUsername" mapIdentifier="BasicAuthCredentials"> <DisplayName>getUsername</DisplayName> <Get assignTo="credentials.username" index="1"> <Key> <Parameter ref="BasicAuth.credentials.username"/> </Key> </Get> <Scope>environment</Scope> </KeyValueMapOperations>
getPassword:this is used to get the password from the key value pairs
<KeyValueMapOperationsname="getPassword" mapIdentifier="BasicAuthCredentials"> <DisplayName>getPassword</DisplayName> <Get assignTo="credentials.password" index="1"> <Key> <Parameter ref="BasicAuth.credentials.password"/> </Key> </Get> <Scope>environment</Scope> </KeyValueMapOperations>
And my basic authentication policy is
<BasicAuthentication name="Basic-Authentication-1"> <DisplayName>Basic Authentication-1</DisplayName> <Operation>Encode</Operation> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> <User ref="BasicAuth.credentials.username"/> <!--<User ref="request.queryparam.username"/>--> <!--<Password ref="request.queryparam.password"/>--> <Password ref="BasicAuth.credentials.password"/> <AssignTo createNew="false">request.header.Authorization</AssignTo> <Source>request.header.Authorization</Source> </BasicAuthentication>
I added header and base 64 encoded of username and password but unfortunately I am getting the following errors:
{"fault": { "faultstring": "Unresolved variable : BasicAuth.credentials.username", "detail": {"errorcode": "steps.basicauthentication.UnresolvedVariable"} }}
Solved! Go to Solution.
Hi, Rajesh
A couple tips here.
First, the documentation for the KeyValueMapOperations policy isn't very clear on this particular point, but I'll tell you: it is possible to use multiple Get elements in a single KeyValueMapOperations policy, if you are intending to retrieve multiple data items from the same map. For example, this is a working policy that I use to retrieve settings for Stackdriver.
<KeyValueMapOperations name='KVM-Get-Stackdriver-Settings' mapIdentifier='settings1'> <Scope>environment</Scope> <ExpiryTimeInSecs>30</ExpiryTimeInSecs> <!-- these gets will be cached --> <Get assignTo='stackdriver.projectid'> <Key> <Parameter>stackdriver.projectid</Parameter> </Key> </Get> <Get assignTo='stackdriver.logid'> <Key> <Parameter>stackdriver.logid</Parameter> </Key> </Get> <Get assignTo='stackdriver.jwt_issuer'> <Key> <Parameter>stackdriver.jwt_issuer</Parameter> </Key> </Get> </KeyValueMapOperations>
That policy retrieves 3 items. In your case, using multiple Get elements in a single policy would also make sense. I'll make sure to get the documentation updated on this point.
#2. When you retrieve from the KVM, you specify a key. This may be obvious, but let me say it anyway because I'm pedantic: the KVM, as the name suggests, maps a key to a value. I can lookup "favorite-fruit" and get "apple". "favorite-fruit" is the key, and "apple" is the value.
In my case from the policy above, I was using "stackdriver.projectid" for the key for one of the data items. And the data returned will be "project-apigee-edge". This is a snap from the administrative UI For Apigee Edge, showing the contents of this KVM:
In the policy configuration I used, the Get element looked like this:
<Get assignTo='stackdriver.projectid'> <Key> <Parameter>stackdriver.projectid</Parameter> </Key> </Get>
That uses a fixed key "stackdriver.projectid" and maps it to a context variable (assignTo), with the same name. They need not be the same name, but I find it simpler to do it this way.
Now, in your configuration, the configuration looks like this:
<Get assignTo="credentials.password" index="1"> <Key> <Parameter ref="credentials.password"/> </Key> </Get>
What that says is ... the key itself is being retrieved from a context variable called "BasicAuth.credentials.password" . That's what the ref= attribute does; it says "get the value from this context variable." I think that's wrong. I think you don't want that. You don't want a variable key. I think maybe what you want is a fixed key, just in the same way that I am specifying a fixed key of "stackdriver.projectuid". I think you want something like this:
<Get assignTo="credentials.password"> <Key> <Parameter>credentials.password</Parameter> </Key> </Get>
Do you see the difference? No ref= attribute. The full policy with the 2 Get elements should be:
<KeyValueMapOperations name="getCredentials" mapIdentifier="BasicAuthCredentials"> <DisplayName>getCredentials</DisplayName> <Get assignTo="credentials.username"> <Key> <Parameter>credentials.username"</Parameter> </Key> </Get> <Get assignTo="credentials.password"> <Key> <Parameter>credentials.password"</Parameter> </Key> </Get> <Scope>environment</Scope> </KeyValueMapOperations>
#3. OK, once that policy executes, the context variable "credentials.password" and "credentials.username" will contain values. That means in your BasicAuthentication policy, you should refer to THOSE variables. Your policy referred to variables with the names BasicAuth.credentials.password, and BasicAuth.credentials.username, which I think is wrong. Also you used the Source element, which is sensible only when the Operation is Decode.
A better config might be:
<BasicAuthentication name="Basic-Authentication-1"> <Operation>Encode</Operation> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> <User ref="credentials.username"/> <Password ref="credentials.password"/> <AssignTo createNew="false">request.header.Authorization</AssignTo> </BasicAuthentication>
Last thing: you should probably consider using an Encrypted KVM, if you are storing secrets there (like passwords).