This problem is not a new one; you have one server that you want to allow select few domains to access. CORS allows you to allow all (*) or a single targeted domain, but each has its restrictions which you can read more about here: (https://www.moesif.com/blog/technical/cors/Authoritative-Guide-to-CORS-Cross-Origin-Resource-Sharing-for-REST-APIs/#).
We could not use *, to allow everyone to connect, because we wanted to enforce credential pass through. So the default way IIS and web.configs for adding a domain via Access-Control-Allow-Origin header failed to meet our needs. Doing some research, I found a Stackoverflow article (https://stackoverflow.com/questions/17323350/access-control-allow-origin-with-multiple-domains) on how you could solve the problem in two ways:
- Add code to your global.asmx and have it check if that origin is in a defined list in your code/config. Then dynamically add that domain to the Access-Control-Allow-Origin header.
- Use URL Rewrite to check for the domain and add it to the origin.
I thought about the first option briefly, but it quickly fell out a favor because the target for this was one single environment. Option two allowed me to update a specific environment the conditional code, and we could keep track of those environments on a watch list for any security concerns.
Steps followed to implement this solution:
- Download and install URL Rewrite from Microsoft (https://www.iis.net/downloads/microsoft/url-rewrite)
- Update the web.config the defined snippet
<system.webServer> <httpProtocol> <customHeaders> <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" /> <add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS,PUT,DELETE" /> </customHeaders> </httpProtocol> <rewrite> <outboundRules> <clear /> <rule name="AddCrossDomainHeader"> <match serverVariable="RESPONSE_Access_Control_Allow_Origin" pattern=".*" /> <conditions logicalGrouping="MatchAll" trackAllCaptures="true"> <add input="{HTTP_ORIGIN}" pattern="(https:\/\/((.+\.)?(domain1|domain2)\.(com|org|net)))" /> </conditions> <action type="Rewrite" value="{C:0}" /> </rule> </outboundRules> </rewrite> </system.webServer>
I used the code snippet nearly verbatim, except the regex pattern. I updated to the suggested pattern defined in the comments as well as making the protocol be strictly https.
So far am pleased with the solution, I am keeping an eye out for the possible issue of caching, as mentioned in the article. However, I have not seen any caching issues with the limited amount of testing done.