{"id":1554,"date":"2013-07-02T23:30:17","date_gmt":"2013-07-02T23:30:17","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/webdev\/2013\/07\/02\/manage-cors-policy-dynamically\/"},"modified":"2022-08-09T07:25:02","modified_gmt":"2022-08-09T14:25:02","slug":"manage-cors-policy-dynamically","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/manage-cors-policy-dynamically\/","title":{"rendered":"Manage CORS policy dynamically"},"content":{"rendered":"<h2>Brief<\/h2>\n<p>We introduced CORS support in ASP.NET Web API a <a href=\"http:\/\/blogs.msdn.com\/b\/yaohuang1\/archive\/2013\/04\/05\/try-out-asp.net-web-api-cors-support-using-the-nightly-builds.aspx\">few months ago<\/a>. Out of the box it supports configuring CORS policy by attributes. It is a very intuitive and powerful way but lacks flexibility at runtime. Imaging your service allows a 3rd party to consume your service. You need the capability of updating the allowing origins list without compiling and deploying your service each time the list changes. <\/p>\n<p>In following this article, I show you two examples of dynamically managing your CORS policy. <\/p>\n<ol>\n<li>Manage your CORS allowed origins in a SQL database.<\/li>\n<li>Manage your CORS allowed origins in the web.config file.<\/li>\n<\/ol>\n<h2>Prerequisites<\/h2>\n<ol>\n<li><a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkId=299058\">Visual Studio Express 2013 Preview for Web<\/a> or <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkId=306566\">Visual Studio 2013 Preview<\/a>.<\/li>\n<li><a href=\"http:\/\/qunitjs.com\/\">QUnit<\/a>.<\/li>\n<li><a href=\"http:\/\/twitter.github.io\/bootstrap\/\">Bootstrap<\/a> (optional)<\/li>\n<\/ol>\n<h2>Set up the test environment<\/h2>\n<h2>CORS Service<\/h2>\n<p>Create a WebAPI project. It comes with a default ValuesController. Mark the controller with EnableCors attribute:<\/p>\n<div class=\"csharpcode\">\n<pre class=\"alt\"><span class=\"lnum\">   1:  <\/span>    [EnableCors(<span class=\"str\">&quot;*&quot;<\/span>, <span class=\"str\">&quot;*&quot;<\/span>, <span class=\"str\">&quot;*&quot;<\/span>)]<\/pre>\n<pre><span class=\"lnum\">   2:  <\/span>    <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">class<\/span> ValuesController : ApiController<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   3:  <\/span>    {<\/pre>\n<pre><span class=\"lnum\">   4:  <\/span>        <span class=\"rem\">\/\/ GET api\/values<\/span><\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   5:  <\/span>        <span class=\"kwrd\">public<\/span> IEnumerable&lt;<span class=\"kwrd\">string<\/span>&gt; Get()<\/pre>\n<pre><span class=\"lnum\">   6:  <\/span>        {<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   7:  <\/span>            <span class=\"kwrd\">return<\/span> <span class=\"kwrd\">new<\/span> <span class=\"kwrd\">string<\/span>[] { <span class=\"str\">&quot;value1&quot;<\/span>, <span class=\"str\">&quot;value2&quot;<\/span> };<\/pre>\n<pre><span class=\"lnum\">   8:  <\/span>        }<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   9:  <\/span>&#160;<\/pre>\n<pre><span class=\"lnum\">  10:  <\/span>        <span class=\"rem\">\/\/ GET api\/values\/5<\/span><\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  11:  <\/span>        <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">string<\/span> Get(<span class=\"kwrd\">int<\/span> id)<\/pre>\n<pre><span class=\"lnum\">  12:  <\/span>        {<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  13:  <\/span>            <span class=\"kwrd\">return<\/span> <span class=\"str\">&quot;value&quot;<\/span>;<\/pre>\n<pre><span class=\"lnum\">  14:  <\/span>        }<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  15:  <\/span>&#160;<\/pre>\n<pre><span class=\"lnum\">  16:  <\/span>        <span class=\"rem\">\/\/ POST api\/values<\/span><\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  17:  <\/span>        <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">void<\/span> Post([FromBody]<span class=\"kwrd\">string<\/span> <span class=\"kwrd\">value<\/span>)<\/pre>\n<pre><span class=\"lnum\">  18:  <\/span>        {<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  19:  <\/span>        }<\/pre>\n<pre><span class=\"lnum\">  20:  <\/span>&#160;<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  21:  <\/span>        <span class=\"rem\">\/\/ PUT api\/values\/5<\/span><\/pre>\n<pre><span class=\"lnum\">  22:  <\/span>        <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">void<\/span> Put(<span class=\"kwrd\">int<\/span> id, [FromBody]<span class=\"kwrd\">string<\/span> <span class=\"kwrd\">value<\/span>)<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  23:  <\/span>        {<\/pre>\n<pre><span class=\"lnum\">  24:  <\/span>        }<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  25:  <\/span>&#160;<\/pre>\n<pre><span class=\"lnum\">  26:  <\/span>        [DisableCors]<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  27:  <\/span>        <span class=\"rem\">\/\/ DELETE api\/values\/5<\/span><\/pre>\n<pre><span class=\"lnum\">  28:  <\/span>        <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">void<\/span> Delete(<span class=\"kwrd\">int<\/span> id)<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  29:  <\/span>        {<\/pre>\n<pre><span class=\"lnum\">  30:  <\/span>        }<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  31:  <\/span>    }<\/pre>\n<\/div>\n<p>Add following line to the <i>App_StartWebApiConfig.cs<\/i> file to enable CORS.<\/p>\n<div class=\"csharpcode\">\n<pre class=\"alt\"><span class=\"lnum\">   1:  <\/span>config.EnableCors();<\/pre>\n<\/div>\n<p>Now your CORS service is set up.<\/p>\n<h2>Test client<\/h2>\n<p>The client code can\u2019t stay in the same service as CORS service since it requires two services hosted at different origins so the CORS mechanism will kick in. <\/p>\n<p>CORS is also affected by the <a href=\"http:\/\/caniuse.com\/cors\">choice of browsers<\/a><a href=\"#_edn1\" name=\"_ednref1\">[i]<\/a>. So the tests need to be run in browser. Therefore I write the test in QUnit<a href=\"#_edn2\" name=\"_ednref2\">[ii]<\/a>.<\/p>\n<p>Create an empty ASP.NET project. Adding following files:<\/p>\n<h3><b>Index.html<\/b><\/h3>\n<div class=\"csharpcode\">\n<pre class=\"alt\"><span class=\"lnum\">   1:  <\/span><span class=\"kwrd\">&lt;!<\/span><span class=\"html\">DOCTYPE<\/span> <span class=\"attr\">html<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<pre><span class=\"lnum\">   2:  <\/span><span class=\"kwrd\">&lt;<\/span><span class=\"html\">html<\/span> <span class=\"attr\">xmlns<\/span><span class=\"kwrd\">=&quot;http:\/\/www.w3.org\/1999\/xhtml&quot;<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   3:  <\/span><span class=\"kwrd\">&lt;<\/span><span class=\"html\">head<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<pre><span class=\"lnum\">   4:  <\/span>    <span class=\"kwrd\">&lt;<\/span><span class=\"html\">title<\/span><span class=\"kwrd\">&gt;<\/span>CORS Test<span class=\"kwrd\">&lt;\/<\/span><span class=\"html\">title<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   5:  <\/span>    <span class=\"kwrd\">&lt;<\/span><span class=\"html\">link<\/span> <span class=\"attr\">href<\/span><span class=\"kwrd\">=&quot;Content\/bootstrap.css&quot;<\/span> <span class=\"attr\">rel<\/span><span class=\"kwrd\">=&quot;stylesheet&quot;<\/span> <span class=\"kwrd\">\/&gt;<\/span><\/pre>\n<pre><span class=\"lnum\">   6:  <\/span><span class=\"kwrd\">&lt;\/<\/span><span class=\"html\">head<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   7:  <\/span><span class=\"kwrd\">&lt;<\/span><span class=\"html\">body<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<pre><span class=\"lnum\">   8:  <\/span>    <span class=\"kwrd\">&lt;<\/span><span class=\"html\">div<\/span> <span class=\"attr\">class<\/span><span class=\"kwrd\">=&quot;container&quot;<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   9:  <\/span>        <span class=\"kwrd\">&lt;<\/span><span class=\"html\">h1<\/span><span class=\"kwrd\">&gt;<\/span>CORS Test Client<span class=\"kwrd\">&lt;\/<\/span><span class=\"html\">h1<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<pre><span class=\"lnum\">  10:  <\/span>        <span class=\"kwrd\">&lt;<\/span><span class=\"html\">p<\/span><span class=\"kwrd\">&gt;<\/span>Input the url to the CORS service in following form.<span class=\"kwrd\">&lt;\/<\/span><span class=\"html\">p<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  11:  <\/span>        <span class=\"kwrd\">&lt;<\/span><span class=\"html\">form<\/span> <span class=\"attr\">action<\/span><span class=\"kwrd\">=&quot;Test.html&quot;<\/span> <span class=\"attr\">method<\/span><span class=\"kwrd\">=&quot;get&quot;<\/span> <span class=\"attr\">class<\/span><span class=\"kwrd\">=&quot;form-inline&quot;<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<pre><span class=\"lnum\">  12:  <\/span>            <span class=\"kwrd\">&lt;<\/span><span class=\"html\">input<\/span> <span class=\"attr\">type<\/span><span class=\"kwrd\">=&quot;text&quot;<\/span> <span class=\"attr\">name<\/span><span class=\"kwrd\">=&quot;url&quot;<\/span> <span class=\"attr\">class<\/span><span class=\"kwrd\">=&quot;input-xxlarge&quot;<\/span> <span class=\"kwrd\">\/&gt;<\/span><\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  13:  <\/span>            <span class=\"kwrd\">&lt;<\/span><span class=\"html\">input<\/span> <span class=\"attr\">type<\/span><span class=\"kwrd\">=&quot;submit&quot;<\/span> <span class=\"attr\">name<\/span><span class=\"kwrd\">=&quot;submit&quot;<\/span> <span class=\"attr\">class<\/span><span class=\"kwrd\">=&quot;btn&quot;<\/span><span class=\"kwrd\">\/&gt;<\/span><\/pre>\n<pre><span class=\"lnum\">  14:  <\/span>        <span class=\"kwrd\">&lt;\/<\/span><span class=\"html\">form<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  15:  <\/span>    <span class=\"kwrd\">&lt;\/<\/span><span class=\"html\">div<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<pre><span class=\"lnum\">  16:  <\/span><span class=\"kwrd\">&lt;\/<\/span><span class=\"html\">body<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  17:  <\/span><span class=\"kwrd\">&lt;\/<\/span><span class=\"html\">html<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<\/div>\n<h3><b>Test.html<\/b><\/h3>\n<div class=\"csharpcode\">\n<pre class=\"alt\"><span class=\"lnum\">   1:  <\/span><span class=\"kwrd\">&lt;!<\/span><span class=\"html\">DOCTYPE<\/span> <span class=\"attr\">html<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<pre><span class=\"lnum\">   2:  <\/span><span class=\"kwrd\">&lt;<\/span><span class=\"html\">html<\/span> <span class=\"attr\">xmlns<\/span><span class=\"kwrd\">=&quot;http:\/\/www.w3.org\/1999\/xhtml&quot;<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   3:  <\/span><span class=\"kwrd\">&lt;<\/span><span class=\"html\">head<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<pre><span class=\"lnum\">   4:  <\/span>    <span class=\"kwrd\">&lt;<\/span><span class=\"html\">title<\/span><span class=\"kwrd\">&gt;<\/span>CORS Test<span class=\"kwrd\">&lt;\/<\/span><span class=\"html\">title<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   5:  <\/span>    <span class=\"kwrd\">&lt;<\/span><span class=\"html\">link<\/span> <span class=\"attr\">href<\/span><span class=\"kwrd\">=&quot;Content\/qunit.css&quot;<\/span> <span class=\"attr\">rel<\/span><span class=\"kwrd\">=&quot;stylesheet&quot;<\/span> <span class=\"kwrd\">\/&gt;<\/span><\/pre>\n<pre><span class=\"lnum\">   6:  <\/span><span class=\"kwrd\">&lt;\/<\/span><span class=\"html\">head<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   7:  <\/span><span class=\"kwrd\">&lt;<\/span><span class=\"html\">body<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<pre><span class=\"lnum\">   8:  <\/span>    <span class=\"kwrd\">&lt;<\/span><span class=\"html\">div<\/span> <span class=\"attr\">id<\/span><span class=\"kwrd\">=&quot;qunit&quot;<\/span><span class=\"kwrd\">&gt;&lt;\/<\/span><span class=\"html\">div<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   9:  <\/span>    <span class=\"kwrd\">&lt;<\/span><span class=\"html\">div<\/span> <span class=\"attr\">id<\/span><span class=\"kwrd\">=&quot;qunit-fixture&quot;<\/span><span class=\"kwrd\">&gt;&lt;\/<\/span><span class=\"html\">div<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<pre><span class=\"lnum\">  10:  <\/span>    <span class=\"kwrd\">&lt;<\/span><span class=\"html\">script<\/span> <span class=\"attr\">src<\/span><span class=\"kwrd\">=&quot;Scripts\/jquery-2.0.2.js&quot;<\/span><span class=\"kwrd\">&gt;&lt;\/<\/span><span class=\"html\">script<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  11:  <\/span>    &lt;script src=<span class=\"str\">&quot;Scripts\/qunit.js&quot;<\/span>&gt;&lt;\/script&gt;<\/pre>\n<pre><span class=\"lnum\">  12:  <\/span>    &lt;script src=<span class=\"str\">&quot;Scripts\/test.js&quot;<\/span>&gt;<span class=\"kwrd\">&lt;\/<\/span><span class=\"html\">script<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  13:  <\/span><span class=\"kwrd\">&lt;\/<\/span><span class=\"html\">body<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<pre><span class=\"lnum\">  14:  <\/span><span class=\"kwrd\">&lt;\/<\/span><span class=\"html\">html<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<\/div>\n<h3><b>Scriptstest.js<\/b><\/h3>\n<div class=\"csharpcode\">\n<pre class=\"alt\"><span class=\"lnum\">   1:  <\/span><span class=\"kwrd\">function<\/span> getParameterByName(name) {<\/pre>\n<pre><span class=\"lnum\">   2:  <\/span>    name = name.replace(\/[[]\/, <span class=\"str\">&quot;\\[&quot;<\/span>).replace(\/[]]\/, <span class=\"str\">&quot;\\]&quot;<\/span>);<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   3:  <\/span>    <span class=\"kwrd\">var<\/span> regex = <span class=\"kwrd\">new<\/span> RegExp(<span class=\"str\">&quot;[\\?&amp;]&quot;<\/span> + name + <span class=\"str\">&quot;=([^&amp;#]*)&quot;<\/span>),<\/pre>\n<pre><span class=\"lnum\">   4:  <\/span>        results = regex.exec(location.search);<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   5:  <\/span>    <span class=\"kwrd\">return<\/span> results == <span class=\"kwrd\">null<\/span> ? <span class=\"str\">&quot;&quot;<\/span> : decodeURIComponent(results[1].replace(\/+\/g, <span class=\"str\">&quot; &quot;<\/span>));<\/pre>\n<pre><span class=\"lnum\">   6:  <\/span>}<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   7:  <\/span>&#160;<\/pre>\n<pre><span class=\"lnum\">   8:  <\/span>test(<span class=\"str\">&quot;Cross domain get request&quot;<\/span>, <span class=\"kwrd\">function<\/span> () {<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   9:  <\/span>    <span class=\"kwrd\">var<\/span> testUrl = getParameterByName(<span class=\"str\">&quot;url&quot;<\/span>);<\/pre>\n<pre><span class=\"lnum\">  10:  <\/span>&#160;<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  11:  <\/span>    <span class=\"kwrd\">var<\/span> xhr = <span class=\"kwrd\">new<\/span> XMLHttpRequest();<\/pre>\n<pre><span class=\"lnum\">  12:  <\/span>    xhr.open(<span class=\"str\">&quot;GET&quot;<\/span>, testUrl + <span class=\"str\">&quot;\/api\/Values&quot;<\/span>, <span class=\"kwrd\">false<\/span>);<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  13:  <\/span>    xhr.send();<\/pre>\n<pre><span class=\"lnum\">  14:  <\/span>&#160;<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  15:  <\/span>    <span class=\"kwrd\">var<\/span> retval = JSON.parse(xhr.responseText);<\/pre>\n<pre><span class=\"lnum\">  16:  <\/span>&#160;<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  17:  <\/span>    equal(2, retval.length);<\/pre>\n<pre><span class=\"lnum\">  18:  <\/span>    equal(<span class=\"str\">&quot;value1&quot;<\/span>, retval[0]);<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  19:  <\/span>    equal(<span class=\"str\">&quot;value2&quot;<\/span>, retval[1]);<\/pre>\n<pre><span class=\"lnum\">  20:  <\/span>});<\/pre>\n<\/div>\n<p>Notes:<\/p>\n<ol>\n<li>The project requires QUnit.js<a><\/a><a><\/a> and QUnit.css. It also includes Bootstrap. Bootstrap is optional.<\/li>\n<li>Index.html is the front page. It accepts a URL to which this test client will sent CORS request to.<\/li>\n<li>Test.html contains QUnit test fixture.<\/li>\n<li>Test.js contains the test case and a utility function to get parameter from query string.<\/li>\n<\/ol>\n<h2>What now?<\/h2>\n<p>Now you have both CORS service and test client. Host them separately in IIS Express or Azure:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/07\/3782.clip_image001_thumb_341F2883.png\"><img decoding=\"async\" title=\"clip_image001\" style=\"border: 0px currentcolor\" border=\"0\" alt=\"clip_image001\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/07\/3782.clip_image001_thumb_341F2883.png\" width=\"260\" height=\"176\" \/><\/a><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/07\/7180.clip_image002_thumb_3AD23206.png\"><img decoding=\"async\" title=\"clip_image002\" style=\"border: 0px currentcolor\" border=\"0\" alt=\"clip_image002\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/07\/7180.clip_image002_thumb_3AD23206.png\" width=\"449\" height=\"132\" \/><\/a><\/p>\n<p>Visit the test client and input the CORS service URL:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/07\/0576.clip_image004_thumb_737CDC13.png\"><img decoding=\"async\" title=\"clip_image004\" style=\"border: 0px currentcolor\" border=\"0\" alt=\"clip_image004\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/07\/0576.clip_image004_thumb_737CDC13.png\" width=\"624\" height=\"207\" \/><\/a><\/p>\n<p>The page will navigate to the test page once you submit the URL:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/07\/2158.clip_image006_thumb_08022B92.png\"><img decoding=\"async\" title=\"clip_image006\" style=\"border: 0px currentcolor\" border=\"0\" alt=\"clip_image006\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/07\/2158.clip_image006_thumb_08022B92.png\" width=\"624\" height=\"221\" \/><\/a><\/p>\n<p>Notice the test passes since the CORS service accepts request from <b>all origins<\/b>.<\/p>\n<h2>Manage your CORS allowed origin in database<\/h2>\n<p>The goal is to save the allowed origin list in database and make CORS components to visit the database at runtime. We will introduce a data model, CRUD views to manage the database and a new CORS attribute to mark your endpoints.<\/p>\n<p>The advantage of using database is that it\u2019s powerful. You can change the policy at runtime without restart the service. The downside is that database is sometime overkill especially when your service is too simple to add a database.<\/p>\n<h2>Create management page <\/h2>\n<h3>Model<\/h3>\n<p>I used Entity Framework for the database. First, let\u2019s create the simplest model:<\/p>\n<div class=\"csharpcode\">\n<pre class=\"alt\"><span class=\"lnum\">   1:  <\/span>    <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">class<\/span> AllowOrigin<\/pre>\n<pre><span class=\"lnum\">   2:  <\/span>    {<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   3:  <\/span>        <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">int<\/span> Id { get; set; }<\/pre>\n<pre><span class=\"lnum\">   4:  <\/span>&#160;<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   5:  <\/span>        <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">string<\/span> Name { get; set; }<\/pre>\n<pre><span class=\"lnum\">   6:  <\/span>&#160;<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   7:  <\/span>        <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">string<\/span> Origin { get; set; }<\/pre>\n<pre><span class=\"lnum\">   8:  <\/span>    }<\/pre>\n<\/div>\n<ul>\n<li>Id is the key for database index;<\/li>\n<li>Name is used to categorize the origin. Multiple origins can have the same name so as to apply them to a specified endpoint;<\/li>\n<li>Origin is the allowed URL origin.<\/li>\n<\/ul>\n<h3>Create Controller and Views by scaffolding<\/h3>\n<p>Now, let\u2019s use the powerful ASP.NET scaffolding to create controller and views for managing allowed origin list.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/07\/7455.clip_image008_thumb_7C6C6E52.jpg\"><img decoding=\"async\" title=\"clip_image008\" style=\"border: 0px currentcolor\" border=\"0\" alt=\"clip_image008\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/07\/7455.clip_image008_thumb_7C6C6E52.jpg\" width=\"624\" height=\"458\" \/><\/a><\/p>\n<p>Let\u2019s add a MVC 5 Controller with read\/write actions and views, using Entity Framework.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/07\/3644.clip_image009_thumb_25E34044.png\"><img decoding=\"async\" title=\"clip_image009\" alt=\"clip_image009\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/07\/3644.clip_image009_thumb_25E34044.png\" width=\"619\" height=\"425\" \/><\/a><\/p>\n<p>Once views and controller are created let\u2019s update the <i>_Layout.cshtml<\/i> file by adding a link to the navigation bar:<\/p>\n<div class=\"csharpcode\">\n<pre class=\"alt\"><span class=\"lnum\">   1:  <\/span>&lt;div <span class=\"kwrd\">class<\/span>=<span class=\"str\">&quot;nav-collapse collapse&quot;<\/span>&gt;<\/pre>\n<pre><span class=\"lnum\">   2:  <\/span>  &lt;ul <span class=\"kwrd\">class<\/span>=<span class=\"str\">&quot;nav&quot;<\/span>&gt;<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   3:  <\/span>    &lt;li&gt;@Html.ActionLink(<span class=\"str\">&quot;Home&quot;<\/span>, <span class=\"str\">&quot;Index&quot;<\/span>, <span class=\"str\">&quot;Home&quot;<\/span>, <span class=\"kwrd\">new<\/span> { area = <span class=\"str\">&quot;&quot;<\/span> }, <span class=\"kwrd\">null<\/span>)&lt;\/li&gt;<\/pre>\n<pre><span class=\"lnum\">   4:  <\/span>    &lt;li&gt;@Html.ActionLink(<span class=\"str\">&quot;API&quot;<\/span>, <span class=\"str\">&quot;Index&quot;<\/span>, <span class=\"str\">&quot;Help&quot;<\/span>, <span class=\"kwrd\">new<\/span> { area = <span class=\"str\">&quot;&quot;<\/span> }, <span class=\"kwrd\">null<\/span>)&lt;\/li&gt;<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   5:  <\/span>    &lt;li&gt;@Html.ActionLink(<span class=\"str\">&quot;CORS Admin&quot;<\/span>, <span class=\"str\">&quot;Index&quot;<\/span>, <span class=\"str\">&quot;CorsAdminOrigin&quot;<\/span>)&lt;\/li&gt;<\/pre>\n<pre><span class=\"lnum\">   6:  <\/span>  &lt;\/ul&gt;<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   7:  <\/span>&lt;\/div&gt;<\/pre>\n<\/div>\n<p>Now the CORS origin management page is ready to go: \n  <br \/><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/07\/6864.clip_image011_thumb_7789BA96.png\"><img decoding=\"async\" title=\"clip_image011\" style=\"border: 0px currentcolor\" border=\"0\" alt=\"clip_image011\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/07\/6864.clip_image011_thumb_7789BA96.png\" width=\"624\" height=\"321\" \/><\/a><\/p>\n<h2>Extend CORS to read allow origin from database<\/h2>\n<p>We will take advantage of one CORS extension point to accomplish our goal:<\/p>\n<h3>ICorsPolicyProvider<\/h3>\n<p>Instances that implement this interface will create a CORS policy based on a given http request. A CORS policy is a rule deciding how the CORS engine will process the CORS request<\/p>\n<div class=\"csharpcode\">\n<pre class=\"alt\"><span class=\"lnum\">   1:  <\/span><span class=\"kwrd\">namespace<\/span> System.Web.Http.Cors<\/pre>\n<pre><span class=\"lnum\">   2:  <\/span>{<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   3:  <\/span>    <span class=\"rem\">\/\/\/ &lt;summary&gt;<\/span><\/pre>\n<pre><span class=\"lnum\">   4:  <\/span>    <span class=\"rem\">\/\/\/ Provides an abstraction for getting the &lt;see cref=&quot;CorsPolicy&quot;\/&gt;.<\/span><\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   5:  <\/span>    <span class=\"rem\">\/\/\/ &lt;\/summary&gt;<\/span><\/pre>\n<pre><span class=\"lnum\">   6:  <\/span>    <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">interface<\/span> ICorsPolicyProvider<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   7:  <\/span>    {<\/pre>\n<pre><span class=\"lnum\">   8:  <\/span>        <span class=\"rem\">\/\/\/ &lt;summary&gt;<\/span><\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   9:  <\/span>        <span class=\"rem\">\/\/\/ Gets the &lt;see cref=&quot;CorsPolicy&quot;\/&gt;.<\/span><\/pre>\n<pre><span class=\"lnum\">  10:  <\/span>        <span class=\"rem\">\/\/\/ &lt;\/summary&gt;<\/span><\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  11:  <\/span>        <span class=\"rem\">\/\/\/ &lt;param name=&quot;request&quot;&gt;The request.&lt;\/param&gt;<\/span><\/pre>\n<pre><span class=\"lnum\">  12:  <\/span>        <span class=\"rem\">\/\/\/ &lt;param name=&quot;cancellationToken&quot;&gt;The cancellation token.&lt;\/param&gt;<\/span><\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  13:  <\/span>        <span class=\"rem\">\/\/\/ &lt;returns&gt;The &lt;see cref=&quot;CorsPolicy&quot;\/&gt;.&lt;\/returns&gt;<\/span><\/pre>\n<pre><span class=\"lnum\">  14:  <\/span>        Task&lt;CorsPolicy&gt; GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken);<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  15:  <\/span>    }<\/pre>\n<pre><span class=\"lnum\">  16:  <\/span>}<\/pre>\n<\/div>\n<p>Out of box EnableCorsAttribute implements ICorsPolicyProvider. It turns all of your settings in the CORS attribute to CORS policy.<\/p>\n<h3>AllowCors<\/h3>\n<p>We won\u2019t use the EnableCors attribute. Instead we create a new attribute:<\/p>\n<div class=\"csharpcode\">\n<pre class=\"alt\"><span class=\"lnum\">   1:  <\/span><span class=\"kwrd\">public<\/span> <span class=\"kwrd\">class<\/span> AllowCorsAttribute : Attribute, ICorsPolicyProvider<\/pre>\n<pre><span class=\"lnum\">   2:  <\/span>{<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   3:  <\/span>    <span class=\"kwrd\">private<\/span> <span class=\"kwrd\">string<\/span> _configName;<\/pre>\n<pre><span class=\"lnum\">   4:  <\/span>&#160;<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   5:  <\/span>    <span class=\"kwrd\">public<\/span> AllowCorsAttribute(<span class=\"kwrd\">string<\/span> name = <span class=\"kwrd\">null<\/span>)<\/pre>\n<pre><span class=\"lnum\">   6:  <\/span>    {<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   7:  <\/span>        _configName = name ?? <span class=\"str\">&quot;Default&quot;<\/span>;<\/pre>\n<pre><span class=\"lnum\">   8:  <\/span>    }<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   9:  <\/span>&#160;<\/pre>\n<pre><span class=\"lnum\">  10:  <\/span>    <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">string<\/span> ConfigName<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  11:  <\/span>    {<\/pre>\n<pre><span class=\"lnum\">  12:  <\/span>        get { <span class=\"kwrd\">return<\/span> _configName; }<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  13:  <\/span>    }<\/pre>\n<pre><span class=\"lnum\">  14:  <\/span>&#160;<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  15:  <\/span>    <span class=\"kwrd\">public<\/span> Task&lt;CorsPolicy&gt; GetCorsPolicyAsync(<\/pre>\n<pre><span class=\"lnum\">  16:  <\/span>        HttpRequestMessage request,<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  17:  <\/span>        CancellationToken cancellationToken)<\/pre>\n<pre><span class=\"lnum\">  18:  <\/span>    {<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  19:  <\/span>        <span class=\"kwrd\">using<\/span> (var db = <span class=\"kwrd\">new<\/span> CorsContext())<\/pre>\n<pre><span class=\"lnum\">  20:  <\/span>        {<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  21:  <\/span>            var origins = db.AllowOrigins.Where(o =&gt; o.Name == ConfigName).ToArray();<\/pre>\n<pre><span class=\"lnum\">  22:  <\/span>&#160;<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  23:  <\/span>            var retval = <span class=\"kwrd\">new<\/span> CorsPolicy();<\/pre>\n<pre><span class=\"lnum\">  24:  <\/span>            retval.AllowAnyHeader = <span class=\"kwrd\">true<\/span>;<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  25:  <\/span>            retval.AllowAnyMethod = <span class=\"kwrd\">true<\/span>;<\/pre>\n<pre><span class=\"lnum\">  26:  <\/span>            retval.AllowAnyOrigin = <span class=\"kwrd\">false<\/span>;<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  27:  <\/span>&#160;<\/pre>\n<pre><span class=\"lnum\">  28:  <\/span>            <span class=\"kwrd\">foreach<\/span> (var each <span class=\"kwrd\">in<\/span> origins)<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  29:  <\/span>            {<\/pre>\n<pre><span class=\"lnum\">  30:  <\/span>                retval.Origins.Add(each.Origin);<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  31:  <\/span>            }<\/pre>\n<pre><span class=\"lnum\">  32:  <\/span>&#160;<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  33:  <\/span>            <span class=\"kwrd\">return<\/span> Task.FromResult(retval);<\/pre>\n<pre><span class=\"lnum\">  34:  <\/span>        }<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  35:  <\/span>    }<\/pre>\n<pre><span class=\"lnum\">  36:  <\/span>}<\/pre>\n<\/div>\n<p>AllowCors attribute derives from System.Attribute and implement ICorsPolicyProvider, therefore it will be picked up by AttributeBasedPolicyProviderFactory. However it accepts only one parameter for its name. The rest of the settings of the policy are read from the database.<\/p>\n<p><em>In this sample, it only loads allowed origin from database. It is for the sake of simplicity. In a real scenario all settings can be saved in database.<\/em><\/p>\n<h2>How does it work<\/h2>\n<h3>Attributes your ValuesController<\/h3>\n<p>Replace the EnableCors attribute with AllowCors attribute for ValuesController:<\/p>\n<div class=\"csharpcode\">\n<pre class=\"alt\"><span class=\"lnum\">   1:  <\/span>[AllowCors(<span class=\"str\">&quot;Values&quot;<\/span>)]<\/pre>\n<pre><span class=\"lnum\">   2:  <\/span><span class=\"kwrd\">public<\/span> <span class=\"kwrd\">class<\/span> ValuesController : ApiController<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   3:  <\/span>{<\/pre>\n<\/div>\n<p>Notice I gave a name \u201cValues\u201d for this scope.<\/p>\n<h3>A negative test<\/h3>\n<p>Now open both test client and the CORS service (remember to redeploy your services) Run your test client you will notice that the tests failed:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/07\/7875.clip_image013_1E57D0D7.png\"><img decoding=\"async\" title=\"clip_image013\" style=\"border: 0px currentcolor\" border=\"0\" alt=\"clip_image013\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/07\/7875.clip_image013_1E57D0D7.png\" width=\"624\" height=\"458\" \/><\/a><\/p>\n<p>The error reads:<\/p>\n<p>SEC7120: Origin http:\/\/corstestclient.azurewebsites.net not found in Access-Control-Allow-Origin header. \n  <br \/><a href=\"http:\/\/sharepoint\/sites\/uifxue\/wptdocshare\/Shared%20Documents\/0\">Test.html<\/a><\/p>\n<p>This is expected since test client is not on the allowed list. <\/p>\n<h3>Add allowed origin<\/h3>\n<p>So go to the CORS service and add test client to allowed list. Remember the name of the CORS policy to apply is \u201cValues\u201d.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/07\/2273.clip_image014_thumb_27B3960B.png\"><img decoding=\"async\" title=\"clip_image014\" style=\"border: 0px currentcolor\" border=\"0\" alt=\"clip_image014\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/07\/2273.clip_image014_thumb_27B3960B.png\" width=\"443\" height=\"194\" \/><\/a><\/p>\n<p>Rerun your test client. Now it passes!<\/p>\n<h2>Manage your CORS allowed origin in web.config<\/h2>\n<p>The goal of this sample is to show you how to manage CORS setting in web.config. <\/p>\n<p>There are multiple benefits to use web.config. First, it doesn\u2019t need recompile and fully redeployed. Second, it\u2019s so simple that you just need a notepad to update the configuration. Last, if you\u2019re using Azure web site, the portal allow you update the settings on the flight.<\/p>\n<p>There a few downside of web.config. It requires service to be started to change the policy. And it doesn\u2019t fit the situation you need configure endpoints differently.<\/p>\n<h2>Adding settings in web.config<\/h2>\n<div class=\"csharpcode\">\n<pre class=\"alt\"><span class=\"lnum\">   1:  <\/span><span class=\"kwrd\">&lt;<\/span><span class=\"html\">appSettings<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<pre><span class=\"lnum\">   2:  <\/span>    <span class=\"kwrd\">&lt;<\/span><span class=\"html\">add<\/span> <span class=\"attr\">key<\/span><span class=\"kwrd\">=&quot;webpages:Version&quot;<\/span> <span class=\"attr\">value<\/span><span class=\"kwrd\">=&quot;3.0.0.0&quot;<\/span> <span class=\"kwrd\">\/&gt;<\/span><\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   3:  <\/span>    <span class=\"kwrd\">&lt;<\/span><span class=\"html\">add<\/span> <span class=\"attr\">key<\/span><span class=\"kwrd\">=&quot;webpages:Enabled&quot;<\/span> <span class=\"attr\">value<\/span><span class=\"kwrd\">=&quot;false&quot;<\/span> <span class=\"kwrd\">\/&gt;<\/span><\/pre>\n<pre><span class=\"lnum\">   4:  <\/span>    <span class=\"kwrd\">&lt;<\/span><span class=\"html\">add<\/span> <span class=\"attr\">key<\/span><span class=\"kwrd\">=&quot;PreserveLoginUrl&quot;<\/span> <span class=\"attr\">value<\/span><span class=\"kwrd\">=&quot;true&quot;<\/span> <span class=\"kwrd\">\/&gt;<\/span><\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   5:  <\/span>    <span class=\"kwrd\">&lt;<\/span><span class=\"html\">add<\/span> <span class=\"attr\">key<\/span><span class=\"kwrd\">=&quot;ClientValidationEnabled&quot;<\/span> <span class=\"attr\">value<\/span><span class=\"kwrd\">=&quot;true&quot;<\/span> <span class=\"kwrd\">\/&gt;<\/span><\/pre>\n<pre><span class=\"lnum\">   6:  <\/span>    <span class=\"kwrd\">&lt;<\/span><span class=\"html\">add<\/span> <span class=\"attr\">key<\/span><span class=\"kwrd\">=&quot;UnobtrusiveJavaScriptEnabled&quot;<\/span> <span class=\"attr\">value<\/span><span class=\"kwrd\">=&quot;true&quot;<\/span> <span class=\"kwrd\">\/&gt;<\/span><\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   7:  <\/span>    <span class=\"kwrd\">&lt;<\/span><span class=\"html\">add<\/span> <span class=\"attr\">key<\/span><span class=\"kwrd\">=&quot;cors:allowOrigins&quot;<\/span> <span class=\"attr\">value<\/span><span class=\"kwrd\">=&quot;http:\/\/localhost:40861&quot;<\/span><span class=\"kwrd\">\/&gt;<\/span><\/pre>\n<\/div>\n<h2>Extend CORS to read allow origin from web.config<\/h2>\n<p>This is quite straightforward if you have gone through the database sample first:<\/p>\n<div class=\"csharpcode\">\n<pre class=\"alt\"><span class=\"lnum\">   1:  <\/span><span class=\"kwrd\">public<\/span> <span class=\"kwrd\">class<\/span> AllowCorsAttribute : Attribute, ICorsPolicyProvider<\/pre>\n<pre><span class=\"lnum\">   2:  <\/span>{<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   3:  <\/span>    <span class=\"kwrd\">private<\/span> <span class=\"kwrd\">const<\/span> <span class=\"kwrd\">string<\/span> keyCorsAllowOrigin = <span class=\"str\">&quot;cors:allowOrigins&quot;<\/span>;<\/pre>\n<pre><span class=\"lnum\">   4:  <\/span>&#160;<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   5:  <\/span>    <span class=\"kwrd\">private<\/span> CorsPolicy _policy;<\/pre>\n<pre><span class=\"lnum\">   6:  <\/span>&#160;<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   7:  <\/span>    <span class=\"kwrd\">public<\/span> Task&lt;CorsPolicy&gt; GetCorsPolicyAsync(<\/pre>\n<pre><span class=\"lnum\">   8:  <\/span>        HttpRequestMessage request, <\/pre>\n<pre class=\"alt\"><span class=\"lnum\">   9:  <\/span>        CancellationToken cancellationToken)<\/pre>\n<pre><span class=\"lnum\">  10:  <\/span>    {<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  11:  <\/span>        <span class=\"kwrd\">if<\/span> (_policy == <span class=\"kwrd\">null<\/span>)<\/pre>\n<pre><span class=\"lnum\">  12:  <\/span>        {<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  13:  <\/span>            var retval = <span class=\"kwrd\">new<\/span> CorsPolicy();<\/pre>\n<pre><span class=\"lnum\">  14:  <\/span>            retval.AllowAnyHeader = <span class=\"kwrd\">true<\/span>;<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  15:  <\/span>            retval.AllowAnyMethod = <span class=\"kwrd\">true<\/span>;<\/pre>\n<pre><span class=\"lnum\">  16:  <\/span>            retval.AllowAnyOrigin = <span class=\"kwrd\">false<\/span>;<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  17:  <\/span>&#160;<\/pre>\n<pre><span class=\"lnum\">  18:  <\/span>            var <span class=\"kwrd\">value<\/span> = ConfigurationManager.AppSettings[keyCorsAllowOrigin];<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  19:  <\/span>&#160;<\/pre>\n<pre><span class=\"lnum\">  20:  <\/span>            <span class=\"kwrd\">if<\/span> (!<span class=\"kwrd\">string<\/span>.IsNullOrEmpty(<span class=\"kwrd\">value<\/span>))<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  21:  <\/span>            {<\/pre>\n<pre><span class=\"lnum\">  22:  <\/span>                <span class=\"kwrd\">foreach<\/span> (var one <span class=\"kwrd\">in<\/span> from v <span class=\"kwrd\">in<\/span> <span class=\"kwrd\">value<\/span>.Split(<span class=\"str\">';'<\/span>)<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  23:  <\/span>                                    <span class=\"kwrd\">where<\/span> !<span class=\"kwrd\">string<\/span>.IsNullOrEmpty(v)<\/pre>\n<pre><span class=\"lnum\">  24:  <\/span>                                    select v)<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  25:  <\/span>                {<\/pre>\n<pre><span class=\"lnum\">  26:  <\/span>                    retval.Origins.Add(one);<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  27:  <\/span>                }<\/pre>\n<pre><span class=\"lnum\">  28:  <\/span>            }<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  29:  <\/span>&#160;<\/pre>\n<pre><span class=\"lnum\">  30:  <\/span>            _policy = retval;<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  31:  <\/span>        }<\/pre>\n<pre><span class=\"lnum\">  32:  <\/span>&#160;<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  33:  <\/span>        <span class=\"kwrd\">return<\/span> Task.FromResult(_policy);<\/pre>\n<pre><span class=\"lnum\">  34:  <\/span>    }<\/pre>\n<pre class=\"alt\"><span class=\"lnum\">  35:  <\/span>}<\/pre>\n<\/div>\n<p>Note: You don\u2019t need to reload policy for every request. Web.config doesn\u2019t change during the life time of a service.<\/p>\n<h2>How it works<\/h2>\n<p>Put your client origin in the web.config and start the service. Run your test client. It just works.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/07\/4670.clip_image015_thumb_0E4B92D1.png\"><img decoding=\"async\" title=\"clip_image015\" style=\"border: 0px currentcolor\" border=\"0\" alt=\"clip_image015\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/07\/4670.clip_image015_thumb_0E4B92D1.png\" width=\"490\" height=\"229\" \/><\/a><\/p>\n<h3>Configure in Azure Web Site Portal<\/h3>\n<p>Here\u2019s a powerful integration sample if you\u2019re using Azure Web Sites to host your service. In the Azure Web Site portal you can configure your application settings:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/07\/0044.clip_image017_thumb_5BE7BF51.png\"><img decoding=\"async\" title=\"clip_image017\" style=\"border: 0px currentcolor\" border=\"0\" alt=\"clip_image017\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/07\/0044.clip_image017_thumb_5BE7BF51.png\" width=\"624\" height=\"161\" \/><\/a><\/p>\n<p>Now you can change the allow list in browser.<\/p>\n<hr align=\"left\" size=\"1\" width=\"33%\" \/>\n<p><a href=\"#_ednref1\" name=\"_edn1\">[i]<\/a> <a href=\"http:\/\/caniuse.com\/cors\">http:\/\/caniuse.com\/cors<\/a><\/p>\n<p><a href=\"#_ednref2\" name=\"_edn2\">[ii]<\/a> <a href=\"http:\/\/qunitjs.com\/\">http:\/\/qunitjs.com\/<\/a><\/p>\n<hr align=\"left\" size=\"1\" width=\"33%\" \/>\n","protected":false},"excerpt":{"rendered":"<p>Brief We introduced CORS support in ASP.NET Web API a few months ago. Out of the box it supports configuring CORS policy by attributes. It is a very intuitive and powerful way but lacks flexibility at runtime. Imaging your service allows a 3rd party to consume your service. You need the capability of updating the [&hellip;]<\/p>\n","protected":false},"author":434,"featured_media":58792,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[197],"tags":[7436,7230],"class_list":["post-1554","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-aspnet","tag-visual-studio-2013","tag-web-api"],"acf":[],"blog_post_summary":"<p>Brief We introduced CORS support in ASP.NET Web API a few months ago. Out of the box it supports configuring CORS policy by attributes. It is a very intuitive and powerful way but lacks flexibility at runtime. Imaging your service allows a 3rd party to consume your service. You need the capability of updating the [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/1554","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/434"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=1554"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/1554\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/58792"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=1554"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=1554"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=1554"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}