CORS 405 Method Not Allowed
cors, iis-8
Solution
My IIS 8 instance is fresh installation, it seems I needed to make some modifications to the `Handler Mappings`
Backup IIS Configuration
In the event that any of the sugggested changes break your existing websites it's best to make a backup of the applicationhost.config file
- Navigate to `C:\Windows\System32\inetsrv\config`
- Make a copy of `applicationhost.config`
Remove Unused Handlers
As a starting point I removed all unused Handler Mappings to reduce the problem space. You can do this by modifying the `applicationhost.config` directly or by using IIS Manager
- Open IIS Manager
- Either on the server node or the individual website node select the Handler Mappings feature
- Manually remove all mappings that you don't need.
My websites are heavily service based and just depend on static files and files with the `.aspx` and `.svc` files extensions. I also manually removed all references to `.NET 2.0` throughout the configuration file.
Add OPTIONS Handler
This seems to be the fix.
- Open IIS Manager
- Either on the server node or the individual website node select the Handler Mappings feature
- In the lefthand column select `Add Module Mapping`
- In the `Add Module Mapping` dialog use the following values.
- `Request path` - `*`
- `Module` - `ProtocolSupportModule`
- `Executable` - [Leave blank]
- `Name` - [Whatever you want]
- Click `Request Restrictions`
- In the `Mapping` tab, unckeck `Invoke handler only if request is mapped to`
- In the `Verbs` tab ensure `OPTIONS` is selected
- In the `Access` tab select `Script`
My resulting Handlers configuration looks like this
<handlers accessPolicy="Read, Script">
<add name="OPTIONS" path="*" verb="OPTIONS" modules="ProtocolSupportModule" resourceType="Unspecified" />
<add name="svc-Integrated-4.0" path="*.svc" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="SecurityCertificate" path="*.cer" verb="GET,HEAD,POST" modules="IsapiModule" scriptProcessor="%windir%\system32\inetsrv\asp.dll" resourceType="File" />
<add name="ISAPI-dll" path="*.dll" verb="*" modules="IsapiModule" resourceType="File" requireAccess="Execute" allowPathInfo="true" />
<add name="PageHandlerFactory-Integrated-4.0" path="*.aspx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.PageHandlerFactory" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="CGI-exe" path="*.exe" verb="*" modules="CgiModule" resourceType="File" requireAccess="Execute" allowPathInfo="true" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="0" />
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />
</handlers>
Problem
I have been following the Mozilla article on how to set up my website to allow Cross-site scripting requests. Using IIS Manager I have added the following HTTP Response Headers ``` Access-Control-Allow-Origin : * Access-Control-Allow-Headers : Origin, SecurityPrivateKeyID Access-Control-Allow-Methods : GET, POST, PUT, DELETE, OPTIONS ``` Despite this I keep getting a `405 Method Not Allowed` when my browsers (Firefox and Chrome) send the pre-flight request with a custom `SecurityPrivateKeyID` header. Request ``` OPTIONS /Service/Json/User.svc/ HTTP/1.1 Host: serviceprovider.com User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Origin: http://client.com Access-Control-Request-Method: GET Access-Control-Request-Headers: securityprivatekeyid Connection: keep-alive ``` Response ``` HTTP/1.1 405 Method Not Allowed Allow: GET Content-Length: 1565 Content-Type: text/html; charset=UTF-8 Server: Microsoft-IIS/8.0 access-control-allow-origin: * Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS Access-Control-Allow-Headers: Origin, SecurityPrivateKeyID Date: Sat, 23 Mar 2013 08:35:03 GMT ``` The service works fine when accessing directly at `http://serviceprovider.com/Service/Json/User.svc/`. Any ideas on what I am doing wrong? [note I have changed my hosts files to point client.com and serviceprovider.com at my machine] [a solution using JSONP will not do as my web service must be able to consume POST, PUT and DELETE methos]