Apigee Proxy passing same host header to target - apigee

I have a simple apigee proxy, but I can see in the trace an issue where the Host header going to the target contains the host of the proxy itself.
i.e. the target gets
Host: xx.apigeename.com
rather than:
Host: my.awsservername.com
The target is on a different domain to the proxy, so it means that the target server is improperly handling the request (404 in this case).
Why is it that Apigee might be sending the exact same host header and not transforming it?
I have tried to explicitly set it, by setting the TargetEndpoint:
<TargetEndpoint name="xyzzy">
<Description/>
<FaultRules/>
<PreFlow name="PreFlow">
<Request>
<Headers>
<Header name="Host">{target.host}</Header>
</Headers>
</Request>
<Response>
</Response>
</PreFlow>
<PostFlow name="PostFlow">
<Request/>
<Response/>
</PostFlow>
<Flows/>
<HTTPTargetConnection>
<Properties/>
<URL>https://{targetBackend}/xyzzy</URL>
<SSLInfo>
<Enabled>true</Enabled>
<Protocols>
<Protocol>TLSv1.2</Protocol>
</Protocols>
</SSLInfo>
</HTTPTargetConnection>
</TargetEndpoint>
The documentation Apigee has on this seems very vague.
It's getting super frustrating. We have other proxies that are working fine without doing anything special.

This seems odd. Apigee should not do that by default. Are you sure that other flows are setup correctly? Anyhow.. you can try to create a AssignMessage policy that adds the correct host.
Take a look at this: https://docs.apigee.com/api-platform/reference/policies/assign-message-policy#Samples
./policies/hostPolicy.xml:
<AssignMessage name="hostPolicy" continueOnError="false">
<AssignTo createNew="false" type="request"></AssignTo>
<Set>
<Headers>
<Header name="Host">{target.host}</Header>
</Headers>
</Set>
</AssignMessage>
./targets/xyzzy.xml
<PreFlow name="PreFlow">
<Request>
<Step>
<Name>hostPolicy</Name>
</Step>
</Request>
</PreFlow>
NB: I haven't tested this. Read the vague apigee docs on policies

For Apigee X, the AssignMessage -> Set option does not work. But two other options are effective:
Javascript: context.setVariable('target.header.host',"my.host.name")
AssignMessage Policy:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage continueOnError="false" enabled="true" name="AM-targethost">
<DisplayName>AM-targethost</DisplayName>
<Properties/>
<AssignVariable>
<Name>target.header.host</Name>
<Value>my.host.name</Value>
<Ref/>
</AssignVariable>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>

Related

How to use BizTalk Health Monitor with an authenticating proxy?

How to use BizTalk Health Monitor with an authenticating proxy?
Is there anyway to use the BHM, specifically the "Repository Update" option, when you're behind an authenticating proxy?
I think you can create a file "ChkBHMRep.exe.config” in the BHM setup folder and update like this :
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.net>
<defaultProxy enabled="true" useDefaultCredentials="true">
<proxy usesystemdefault="true" />
</defaultProxy>
</system.net>
</configuration>
It is indeed ChkBHMRep.exe which checks for BHM repositories updates
Let me know if it works
JP Auconie
BHM team

Transform the content-type in apigee

Our application needs the request to be application/xml or text/xml.
However sometimes client forget and send without content type specification.
Is it possible to add an apigee policy to add the content-type if not added?
The simplest thing would be to set the content type for all incoming messages. The easiest way to do this is through an Assign Message policy. Sample code for setting headers is as follows:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="AssignAuthHeaders">
<DisplayName>AssignAuthHeaders</DisplayName>
<FaultRules/>
<Properties/>
<Add>
<Headers>
<Header name="oAuthToken">{access_token}</Header>
<Header name="appId">{client_id}</Header>
<Header name="EncryptedHHonorsNumber">{accesstoken.encrypted_hhonors}</Header>
</Headers>
</Add>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</AssignMessage>
I haven't tried this myself, but you could delete all the Header entries above and put
<Header name="Content-Type">application/xml</Header>

Apigee proxy SSL CLASSIFICATION_FAILURE 404 vs. 301 REDIRECT

When I have an API that only accepts HTTPS and I make an HTTP request the default seems to be a 404 error. Is there a way to automatically redirect to the HTTPS URL?
One easy way to do this is with a conditional RaiseFault policy.
Here's a simple example of
The RaiseFault policy looks as follows:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<RaiseFault async="false" continueOnError="false" enabled="true" name="301tossl">
<DisplayName>301toSSL</DisplayName>
<FaultRules/>
<Properties/>
<FaultResponse>
<Set>
<Headers>
<Header name="Location">https://{request.header.host}{request.uri}</Header>
</Headers>
<Payload contentType="text/plain">SSL Required.
</Payload>
<StatusCode>301</StatusCode>
<ReasonPhrase>Moved Permanently</ReasonPhrase>
</Set>
</FaultResponse>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</RaiseFault>
And the here's an example of putting a condition on the policy (in the preflow in this case):
<PreFlow name="PreFlow">
<Request>
<Step>
<FaultRules/>
<Name>301tossl</Name>
<Condition>client.scheme = "http"</Condition>
</Step>
</Request>
<Response/>
</PreFlow>
I've got a sample here if you want to download ->
https://github.com/carloseberhardt/edge-samples/tree/master/proxies/301ssl
I would go with similar approach described here of catch all and redirect. Catch all proxy always redirects. You need not raise a fault, you can do it in response flow of catch all proxy.

Authentication issue in jsonp ria services

I am using ria services with jsonp endpoint. When I call my method in service file it works fine in ie and firefox but sometimes works in chrome and sometimes I get "Cross domain javascript callback is not supported in authenticated services." error. Even I dont use authenticated services.
Here is a piece of code about what I have.
Jsonp service
[EnableClientAccess(RequiresSecureEndpoint = false)]
public class PPolJsonService : LinqToEntitiesDomainService<PPolAdvEntities>
{
public IQueryable<QuestionEntity> GetCompleteSurvey()
{
............
}
}
javascript code
function (data) {
var Params = {};
Params.type = 'GET';
Params.url = 'http://127.0.0.1:81/PPolSilverlight-Web-Services-PPolJsonService.svc/JSONP/GetCompleteSurvey;
Params.dataType = 'jsonp';
Params.data = { data:'somedata'};
Params.success = function (data) { };
Params.jsonpCallback = "ppolv2"
$.ajax(Params);
});
In web.config file my setting is <authentication mode="Forms">
İf I set <authentication mode="None"> I am be able to solve all problems with chrome. But the rest of the application needs authentication. So thats why I have to use it as "mode=Forms". And as you see my service does not use authentication so,
Why I am getting this error and is there any solution for it?
Note:
By the way I have other settings in web.config like
<webHttpEndpoint>
<standardEndpoint crossDomainScriptAccessEnabled="true"
automaticFormatSelectionEnabled="true"/>
</webHttpEndpoint>
or these in clientaccesspolicy.xml
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="*">
<domain uri="http://*"/>
<domain uri="https://*" />
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
but none of them is helping me.
Thanks in advance.
Hi Try to add this line to your web.config files. It enables Cross-domain Ajax Requests.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
I haven't test it enough but I guess I found a solution.
İf you use secure endpoint in your application and if you don't need to use secure endpoint for jsonp services,
you can add requireSSL="true" in
<authentication mode="Forms">
<forms name=".PPolSilverlight_ASPXAUTH" timeout="2880" requireSSL="true" />
</authentication>
with this small piece of code your unsecure jsonp services will be able to work without authentication.

How to log/debug bad requests in tomcat?

In our system (closed system, java web application in tomcat 6 as server, java fat clients) our clients show occasionally "400 - Bad Request" responses. I would like to debug this on the server side, but since the requests seem to be invalid, I don't see them anywhere. I configured the AccessLogValve for the complete tomcat host, but the requests don't appear there. I don't even see anything in catalina.out.
I would love to get these requests logged and even better would be to dump requests based on certain criteria.
Any ideas?
My server.xml looks like this:
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="off" />
<Listener className="org.apache.catalina.core.JasperListener" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener"
rmiServerPortPlatform="9098"
rmiRegistryPortPlatform="9099"
useLocalPorts="true" />
<Service name="Catalina">
<Connector port="8020" protocol="HTTP/1.1" redirectPort="8010" connectionTimeout="20000" />
<Engine name="Catalina" defaultHost="localhost" jvmRoute="cc1">
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="false"
deployOnStartup="true" xmlValidation="false" xmlNamespaceAware="false">
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs" prefix="access_log."
suffix=".txt" pattern="combined" resolveHosts="false" />
</Host>
</Engine>
</Service>
</Server>
long time ago - but anyway: Tomcat has different Valves that may help to achieve that: http://tomcat.apache.org/tomcat-6.0-doc/config/valve.html#Request_Dumper_Valve
Another option would be tcpdump since it is HTTP and a response code it seems possible to filter the raw requests that cause this.

Resources