I work on a third party web based application, lets call it Po, by injecting company required modifications via JQuery which calls PHP code in a digital workplace type domain of ours https://digitalworkplace.staging.c.com
The digital workplace code then calls our API, using CURL and POST, which is on a different domain of ours, http://p.staging.c.com
This was previously all working fine until Po added in CSFR support on each of their application pages.
I get the CSRF token from the Po page where it is hidden in a field with id="csrf-nonce", name="CSRF_NONCE"
I make the AJAX call with the following settings:
$.ajaxSetup({
headers: {
'Content-Type': 'application/json; charset=UTF-8',
'CSRF_NONCE' : csrf
}
});
$.ajaxPrefilter(function(options){
options.beforeSend = function(xhr){
xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
xhr.setRequestHeader('CSRF_NONCE', csrf);
}
});
$.ajax({
type: "POST",
accept: 'application/json',
crossOrigin: true,
crossDomain: true,
method: m,
beforeSend: function(xhr){
xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
xhr.setRequestHeader('CSRF_NONCE', csrf);
},
url: u,
data: d,
dataType: "json",
contentType: "application/json",
swotId: s,
async: a,
headers: {
"Content-Type": "application/json; charset=UTF-8",
"CSRF_NONCE": csrf,
},
xhrFields: {
withCredentials: true
},
success: function(xhr) {
console.log("yippee");
},
error: function(e) {
console.log(e);
}
});
If I run in Chrome and look at the Network info I see the General Header:
Request URL:https://digitalworkplace.staging.c.com/web/p/versio/mysql/getmasterordernumber
Request Method:OPTIONS
Status Code:200 OK
Remote Address:192.168.253.11:443
And the Response Headers is:
Allow:OPTIONS, TRACE, GET, HEAD, POST
Content-Length:0
Date:Mon, 27 Mar 2017 11:09:45 GMT
Public:OPTIONS, TRACE, GET, HEAD, POST
Server:Microsoft-IIS/8.5
This looks like IIS 8.5 is responding to the preflight request.
To try and prevent this in IIS I have added into web.config the following:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="false">
<remove name="FormsAuthenticationModule" />
<remove name="WebDavModule" />
</modules>
<handlers>
<remove name="WebDav" />
<remove name="OPTIONS" />
<remove name="OPTIONSVerbHandler" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
<rewrite>
<rules>
<rule name="Strategy to RedSlim" stopProcessing="true">
<match url="^strategy" />
<action type="Rewrite" url="framework/RedSlim/web/" />
</rule>
</rules>
</rewrite>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type: application/json; charset=UTF-8, Accept, CSRF_NONCE" />
<add name="Access-Control-Allow-Methods" value="GET, PUT, POST, DELETE, OPTIONS" />
<add name="Access-Control-Max-Age" value="1000" />
</customHeaders>
</httpProtocol>
<httpErrors errorMode="Detailed" />
<security>
<authorization>
<remove users="" roles="Users" verbs="GET" />
<add accessType="Allow" users="?" roles="" verbs="GET, POST" />
</authorization>
<requestFiltering>
<alwaysAllowedUrls>
<add url="//p.staging.c.com" />
<add url="//digitalworkplace.staging.c.com" />
</alwaysAllowedUrls>
<verbs>
<add verb="OPTIONS" allowed="true" />
<add verb="POST" allowed="true" />
</verbs>
</requestFiltering>
</security>
</system.webServer>
</configuration>
It seems to me that something is wrong with the IIS setup.
In Chrome I can see the POST request header as below but then no response.
Accept:*/*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Access-Control-Request-Headers:access-control-allow-headers, access-control-allow-methods, access-control-allow-origin, content-type, csrf_nonce
Access-Control-Request-Method:POST
Connection:keep-alive
Host:digitalworkplace.staging.c.com
Origin:http://p.staging.c.com
Referer:http://p.staging.c.com/pagesUTF8/auftrag_allgemeinauftrag.jsp?OSG08=24370
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
Does anyone have any suggestion of what else I need to do to allow the POST request to function after the preflight?