Apigee pass Authorization header - apigee

We have Apigee passing calls directly to our backend services.
However Apigee seems to remove the headers for Authorization: Bearer
How can I force Apigee to keep Authorization headers and not strip them out

Try to check in your service, in Remove Header Authorization (it is policy that auto created by apigee) you will see the code below:
<Remove>
<Headers>
<Header name="Authorization"/>
<Header name="Accept"/>
<Header name="accept-encoding"/>
<Header name="cache-control"/>
<Header name="cookie"/>
<Header name="Postman-Token"/>
</Headers>
</Remove>
So, you have to remove <Header name="Authorization"/>

Yes Pim, that is correct, just to be more precise while generating a proxy, Apigee will add below Policy code by default-
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="remove-header-authorization">
<DisplayName>Remove Header Authorization</DisplayName>
<Remove>
<Headers>
<Header name="Authorization"/>
</Headers>
</Remove>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>

Related

Assign Message Policy does not work on Error responses

In Apigee, the Assign Message Policy only seems to work on successful responses. If the server responds with an error code, say, 403 Forbidden, the policy does not change the response. Is there any other way to modify error responses in Apigee.
This is my policy.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="Assign-Message-1">
<DisplayName>Assign Message-1</DisplayName>
<Properties/>
<Remove>
<Headers>
<Header name="Server"/>
</Headers>
</Remove>
<AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>
You can modify error responses in Apigee using FaultRules. You can take a look at Apigee's documentation about Fault handling .
The reason your AssignMessage policy is not executed is, that the error happens before your policy is being executed, thus being skipped.
You can either move your AssignMessage policy to be executed earlier in the flow or catch the error using fault handling logic and throw the error when you have executed all the desired logic.
In case of different response message of Success and Error,
I usually create 2 policy of Assign Message, one for Success and other for Error response.
Example of Success:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="AM-ReturnSuccessResponse">
<DisplayName>AM-ReturnSuccessResponse</DisplayName>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="response"/>
<Set>
<Payload contentType="application/json" variablePrefix="#" variableSuffix="#">
#resp.responseMessage#
</Payload>
<StatusCode>{resp.httpStatusCode}</StatusCode>
<ReasonPhrase>{resp.reasonPhrase}</ReasonPhrase>
</Set>
</AssignMessage>
Example of Error:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <AssignMessage async="false" continueOnError="false" enabled="true" name="AM-ReturnErrorResponse">
<DisplayName>AM-ReturnErrorResponse"</DisplayName>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="response"/>
<Properties/>
<Set>
<Payload contentType="application/json" variablePrefix="#" variableSuffix="#">
{
"error" : "#resp.error#",
"timeStamp" : "#resp.responseDateTime#"
}
</Payload>
<StatusCode>{resp.httpStatusCode}</StatusCode>
<ReasonPhrase>{resp.reasonPhrase}</ReasonPhrase>
</Set> </AssignMessage>
And then in your flow you have to set condition for routing the policy like this
<Flow name="test">
<Description/>
<Request/>
<Response>
<Step>
<Name>AM-ReturnSuccessResponse</Name>
<Condition>resp.httpStatusCode == 200</Condition>
</Step>
<Step>
<Name>AM-ReturnErrorResponse</Name>
<Condition>resp.httpStatusCode != "200"</Condition>
</Step>
</Response>
</Flow>
Remark: Because normally http status code for success is 200, So I have set the condition like code above. But this is for example, you can design the condition up to your scenario.

Call mediator end point type(XPath)

In call mediator we can form endpoint using XPath (from the response).But the problem is endpoint is not calling.
<?xml version="1.0" encoding="UTF-8"?>
<api context="/xpath" name="call"
xmlns="http://ws.apache.org/ns/synapse">
<resource methods="GET" protocol="http">
<inSequence>
<call>
<endpoint key-expression="/root/a"/>
</call>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
following response is from postman.
<root>
<a>http://www.mocky.io/v2/5ca6db71340000132f76b192</a>
</root>
Expected response :
<root>
<name>abcd</name>
<no>82382832</no>
</root>
Firstly, when using the resolving endpoint (using key-expression), we cannot give the URL directly [1]. We have to have the endpoint defined beforehand and should give only the key of the endpoint in the payload.
Secondly, for the key-expression to parse the xpath, the message should be built beforehand. Since call mediator is content-unaware, it will not build the message. Therefore, we should use a content aware mediator to build the message.
Following is the sample inSequence that'd work.
<inSequence>
<log level="full"/>
<call>
<endpoint key-expression="//a"/>
</call>
<respond/>
</inSequence>
Now the payload should be like
<root>
<a>testEndpoint</a>
</root>
Edit:
The endpoint named 'testEndpoint' should be defined with the backend url.
You need to define an endpoint [2]. For example, I'm using an address endpoint.
<endpoint xmlns="http://ws.apache.org/ns/synapse" name="testEndpoint">
<address uri="http://www.mocky.io/v2/5ca6db71340000132f76b192">
<suspendOnFailure>
<progressionFactor>1.0</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
<retryDelay>0</retryDelay>
</markForSuspension>
</address>
</endpoint>
Try this. I receieved needed response in Postman, but you should use POST method as your request has a Body.
<api xmlns="http://ws.apache.org/ns/synapse" name="call" context="/xpath">
<resource methods="POST">
<inSequence>
<property name="uri.var.httpendpointurl" expression="$body/root/a" scope="default" type="STRING"/>
<call>
<endpoint>
<http uri-template="{uri.var.httpendpointurl}"/>
</endpoint>
</call>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>

Mule CE 3.6.1 HTTP Request url encoding issue

I have a Mule flow which uses HTTP Request endpoint in Mule CE3.6.1. It needs to use encoded HTTP url to get the correct data.
Please note the encoded url: /items?q=%2Blabel%3ABOTV2309H*%20%2Bparent.uri%3A%5C%2Fbristol%5C%2Ftest%5C%2Fgateway%5C%2F*&rows=100&start=0
Here is the test flow.
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans" version="CE-3.6.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd">
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8089" basePath="/" usePersistentConnections="false" doc:name="HTTP Listener Configuration"/>
<http:request-config name="HTTP_Request_Config_Search" host="testserver" port="80" basePath="/index" usePersistentConnections="false" doc:name="HTTP Request Configuration"/>
<flow name="testFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="*" allowedMethods="POST" doc:name="HTTP"/>
<object-to-string-transformer doc:name="Object to String"/>
<logger level="INFO" doc:name="Logger"/>
<http:request config-ref="HTTP_Request_Config_Search" path="/items?q=%2Blabel%3ABOTV2309H*%20%2Bparent.uri%3A%5C%2Fbristol%5C%2Ftest%5C%2Fgateway%5C%2F*&rows=100&start=0" method="GET" doc:name="HTTP"/>
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
</flow>
</mule>
When the Mule flow runs, here is the url being requested (Found through wireshark):
/items?q=%20label%3ABOTV2309H%2A%20%20parent.uri%3A%5C%2Fbristol%5C%2Ftest%5C%2Fgateway%5C%2F%2A&rows=100&start=0
Please note %2B is replaced with %20 in two places, which obviously do not return the data I need.
Is this an issue with HTTP endpoint?
Thanks!
I divided the params into query and uri params. Then this issue got resolved.
<http:request config-ref="HTTP_Request_Config_Search" path="/items" method="GET" doc:name="HTTP">
<http:request-builder>
<http:query-param paramName="q" value="+label:BOTV2309H* +parent.uri:\/test\/gateway\/*"/>
<http:uri-param paramName="rows" value="100"/>
<http:uri-param paramName="start" value="0"/>
</http:request-builder>
</http:request>

Websphere - Set content type/charset of external resource

I have mapped static content (html) to external directory. When I request html file over HTTP, it returned content type/charset Windows-874.
Content-Type:text/html; charset=Windows-874
I would like to change it to
Content-Type:text/html; charset=UTF-8
How can I change it in 'ibm-web-ext.xml'? Or I have to change it in other configurations of Websphere?
Here is my ibm-web-ext.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-ext
xmlns="http://websphere.ibm.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-ext_1_0.xsd"
version="1.0">
<file-serving-attribute name="extendedDocumentRoot" value="D:/XXX/content/" />
<reload-interval value="3"/>
<auto-encode-requests value="false"/>
<auto-encode-responses value="false"/>
<enable-directory-browsing value="false"/>
<enable-file-serving value="true"/>
<pre-compile-jsps value="false"/>
<enable-reloading value="true"/>
<enable-serving-servlets-by-class-name value="false" />
</web-ext>

How to extract variable from SOAP request in Edge policy?

Here's my policy:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables async="false" continueOnError="false" enabled="true" name="extract-operation">
<DisplayName>extract-operation</DisplayName>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
<Source clearPayload="true">request.content</Source>
<VariablePrefix>apigee</VariablePrefix>
<XMLPayload stopPayloadProcessing="false">
<Namespaces>
<Namespace prefix="soapenv">http://schemas.xmlsoap.org/soap/envelope/</Namespace>
</Namespaces>
<Variable name="operation" type="string">
<XPath>/soapenv:Envelope/soapenv:Body</XPath>
</Variable>
</XMLPayload>
</ExtractVariables>
In trace tool I see that request.content resolves fine and shows the content, but I was expecting apigee.operation to be populated with the contents of . What am I doing wrong?
Fixed Policy:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables async="false" continueOnError="false" enabled="true" name="extract-operation">
<DisplayName>extract-operation</DisplayName>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
<Source clearPayload="true">request.content</Source>
<XMLPayload stopPayloadProcessing="false">
<Namespaces>
<Namespace prefix="soapenv">http://schemas.xmlsoap.org/soap/envelope/</Namespace>
</Namespaces>
<Variable name="operation" type="nodeset">
<XPath>/soapenv:Envelope/soapenv:Body</XPath>
</Variable>
</XMLPayload>
</ExtractVariables>
If you know the Xpath you don't really need the scema and then you take on more variable out of the equation (ie whether the schema is valid). Then you could just reference //Body (or wherever it is in the xml)

Resources