Transform the content-type in apigee - 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>

Related

Apigee Proxy passing same host header to target

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>

ASP.Net /IIS CORS Access-Control-Allow-Origin:* not working for all requests

I have enabled CORS by adding below to webconfig but it doesnt seems to work consistently:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
If we add an "Origin" header in the request, it does show Access-Control-Allow-Origin:* headers in response. But if we don't add "Origin" header in the request, the server doesn't return Access-Control-Allow-Origin:* headers.
The issue is, I am using sw-toolbox to precache static resources. But if a resource such as javascript files is already in browser cache before service worker is activated, for example the file is directly referenced in the html page and browser has already downloaded and cached the file, it shows CORS error when service worker tries to precache that file.

How can I remove excessive response header information from Azure Web-Apps?

I have an MVC project that I deploy on Azure Web-Apps. I'm trying to remove the excessive header information. The reason I'm trying to remove this information is because it's a standard security practice. (Reference)
I'm trying to remove the below information from response headers:
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-POWERED-BY: PHP/5.4.38
X-POWERED-BY: ASP.NET
I have the following code in my Global.asax.cs file:
protected void Application_PreSendRequestHeaders()
{
Response.Headers.Remove("Server");
Response.Headers.Remove("X-AspNet-Version");
Response.Headers.Remove("X-AspNetMvc-Version");
}
But it's not effecting the result.
Try this instead:
protected void Application_PreSendRequestHeaders(object sender, EventArgs e)
{
HttpContext.Current.Response.Headers.Remove("Server");
HttpContext.Current.Response.Headers.Remove("X-AspNet-Version");
HttpContext.Current.Response.Headers.Remove("X-AspNetMvc-Version");
}
Additionally, in the Application_Start call it with the following instruction
PreSendRequestHeaders += Application_PreSendRequestHeaders;
To remove X-AspNet-Version, in the web.config find/create and add:
<system.web>
<httpRuntime enableVersionHeader="false" />
...
</system.web>
To remove X-AspNetMvc-Version, go to Global.asax, find/create the Application_Start event and add a line as follows:
protected void Application_Start() {
MvcHandler.DisableMvcResponseHeader = true;
}
To remove X-Powered-By, in the web.config find/create and add:
<system.webServer>
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By" />
</customHeaders>
</httpProtocol>
...
</system.webServer>
You should be able to force all requests to go through your managed code by adding this to your webconfig:
<modules runAllManagedModulesForAllRequests="true">
Even static files and not-found resources should obey your header rules.
References:
http://www.troyhunt.com/2012/02/shhh-dont-let-your-response-headers.html
http://consultingblogs.emc.com/howardvanrooijen/archive/2009/08/25/cloaking-your-asp-net-mvc-web-application-on-iis-7.aspx
Don't use code to remove response headers. It is unstable according Microsoft
Use the Web.config custom Headers section instead as defined here:
<system.webServer>
<httpProtocol>
<!-- Security Hardening of HTTP response headers -->
<customHeaders>
<!--Sending the new X-Content-Type-Options response header with the value 'nosniff' will prevent
Internet Explorer from MIME-sniffing a response away from the declared content-type. -->
<add name="X-Content-Type-Options" value="nosniff" />
<!-- X-Frame-Options tells the browser whether you want to allow your site to be framed or not.
By preventing a browser from framing your site you can defend against attacks like clickjacking.
Recommended value "x-frame-options: SAMEORIGIN" -->
<add name="X-Frame-Options" value="SAMEORIGIN" />
<!-- Setting X-Permitted-Cross-Domain-Policies header to “master-only” will instruct Flash and PDF files that
they should only read the master crossdomain.xml file from the root of the website.
https://www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html -->
<add name="X-Permitted-Cross-Domain-Policies" value="master-only" />
<!-- X-XSS-Protection sets the configuration for the cross-site scripting filter built into most browsers.
Recommended value "X-XSS-Protection: 1; mode=block". -->
<add name="X-Xss-Protection" value="1; mode=block" />
<!-- Referrer-Policy allows a site to control how much information the browser includes with navigations away from a document and should be set by all sites.
If you have sensitive information in your URLs, you don't want to forward to other domains
https://scotthelme.co.uk/a-new-security-header-referrer-policy/ -->
<add name="Referrer-Policy" value="no-referrer-when-downgrade" />
<!-- Remove x-powered-by in the response header, required by OWASP A5:2017 - Do not disclose web server configuration -->
<remove name="X-Powered-By" />
<!-- Set the cache-control per your Security settings (will affect performance) -->
<add name="Cache-Control" value="No-cache" />
</customHeaders>
</httpProtocol>
<!-- Prerequisite for the <rewrite> section
Install the URL Rewrite Module on the Web Server https://www.iis.net/downloads/microsoft/url-rewrite -->
<rewrite>
<!-- Remove Server response headers (OWASP Security Measure) -->
<outboundRules rewriteBeforeCache="true">
<rule name="Remove Server header">
<match serverVariable="RESPONSE_Server" pattern=".+" />
<!-- Use custom value for the Server info -->
<action type="Rewrite" value="Your Custom Value Here." />
</rule>
</outboundRules>
</rewrite>
</system.webServer>

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.

Resources