Is there a way to setup the Verify API Key policy to have it look for either a query parameter OR a form parameter? We would like the calling part to be able to provide it in either place.
Solved! Go to Solution.
I guess we can use the ref attribute and reference variable value coming in query or form param,
<VerifyAPIKey async="false" continueOnError="false" enabled="true" name="Verify-API-Key-1"> <DisplayName>Custom label used in UI</DisplayName> <APIKey ref="variable_containing_api_key"/> </VerifyAPIKey>
Before this policy maybe use a JS to get key from either query/form param and set it to a variable. You can also use a couple of extract variable policies with appropiate conditions to set a variable.
It's a good practice to pass the API key in a header or form parameter rather than in a query parameter. The reason is that query parameters can show up in browser histories and network logs, which could present a possible security risk.
I guess we can use the ref attribute and reference variable value coming in query or form param,
<VerifyAPIKey async="false" continueOnError="false" enabled="true" name="Verify-API-Key-1"> <DisplayName>Custom label used in UI</DisplayName> <APIKey ref="variable_containing_api_key"/> </VerifyAPIKey>
Before this policy maybe use a JS to get key from either query/form param and set it to a variable. You can also use a couple of extract variable policies with appropiate conditions to set a variable.
It's a good practice to pass the API key in a header or form parameter rather than in a query parameter. The reason is that query parameters can show up in browser histories and network logs, which could present a possible security risk.
I assume in this case some other policy needs to set variable_containing_api_key? What would that look like?
Before this policy maybe use a JS to get key from either query/form param and set it to a variable. You can also use a couple of extract variable policies with appropiate conditions to set a variable.
Do you have an example of what that javascript would look like? From my research it looks like there is the ability to iterate over request.queryparam, is there also a request.formparam?
Also, once you find the apikey, do you just set it to a global javascript variable and that will be accessible from the VerifyAPIKey policy as long as I provide the same name?
I don't have a JS example right now, use the below logic for the time being,
For both cases users need to send x-api-key in below policies,
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <ExtractVariables async="false" continueOnError="false" enabled="true" name="Extract-Query"> <DisplayName>Extract-Query</DisplayName> <!-- Query parameter --> <Properties/> <URIPath name="name"/> <QueryParam name="x-api-key"> <Pattern ignoreCase="true">{apikey}</Pattern> </QueryParam> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> <Source clearPayload="false">request</Source> <VariablePrefix>apigee</VariablePrefix> </ExtractVariables>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <ExtractVariables async="false" continueOnError="false" enabled="true" name="Extract-Form"> <DisplayName>Extract-Form</DisplayName> <!-- form parameter --> <Properties/> <FormParam name="x-api-key"> <Pattern ignoreCase="true">{apikey}</Pattern> </FormParam> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> <Source clearPayload="false">request</Source> <VariablePrefix>apigee</VariablePrefix> </ExtractVariables>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <VerifyAPIKey async="false" continueOnError="false" enabled="true" name="Verify-API-Key-1"> <DisplayName>Verify API Key-1</DisplayName> <Properties/> <APIKey ref="apigee.apikey"/> </VerifyAPIKey>
<PreFlow name="PreFlow"> <Request> <Step> <Name>Extract-Query</Name> <Condition>request.queryparam.x-api-key != null</Condition> </Step> <Step> <Name>Extract-Form</Name> <Condition>request.formparam.x-api-key != null</Condition> </Step> <Step> <Name>Verify-API-Key-1</Name> </Step> </Request> <Response/> </PreFlow>
Really appreciate the examples and I was able to get these working. Related but not part of this exact original question; is there a way to allow the form parameter to be case insensitive? Meaning, if I pass in x-api-key or x-API-key, either would work. Or in this case, would the javascript scenario be better?
Yes, I guess we need to use JS for case-insensitive paramters. Let me check and give a example. BTW I am posting different answers for easy readability.
Hi @Nick Olsen, I hope you got the answer to this question. I guess this thread is not a good place to discuss case-insensitive form params query. Kindly accept this answer and post a new question.
Fair enough. Other question posted here: https://community.apigee.com/questions/65607/javascript-policy-to-pull-out-query-or-form-parame.html
Instead of using Extract Variable policy, use Javascript,
var queryParam = context.getVariable("request.queryparam.x-api-key"); var formParam = context.getVariable("request.formparam.x-api-key"); if (queryParam !== null){ context.setVariable("apigee.apikey",queryParam); }else{ context.setVariable("apigee.apikey",formParam); }
Use a Raise Fault before JS policy to check missing query/form params,
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <RaiseFault async="false" continueOnError="false" enabled="true" name="Raise-Fault-1"> <DisplayName>Raise Fault-1</DisplayName> <Properties/> <FaultResponse> <Set> <Headers/> <Payload contentType="application/json"> { "error":"Missing x-api-key in query/form param" } </Payload> <StatusCode>404</StatusCode> <ReasonPhrase>Missing Key</ReasonPhrase> </Set> </FaultResponse> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> </RaiseFault>
<PreFlow name="PreFlow"> <Request> <Step> <Name>Raise-Fault-1</Name> <Condition>(request.queryparam.x-api-key = null) and (request.formparam.x-api-key = null) </Condition> </Step> <Step> <Name>JavaScript-1</Name> </Step> <Step> <Name>Verify-API-Key-1</Name> </Step> </Request> <Response/> </PreFlow>
User | Count |
---|---|
7 | |
2 | |
2 | |
1 | |
1 |