title: How to combine ASP.NET Forms Authentication for a single page app/static html web site and a web api service
body: <p>I am working on a single page app implemented as static html files making AJAX request to an Web Api web service. It is hosted on an IIS 7.5.</p>
  
  <p>I have problems getting authentication on static html files to work, when users have authenticated themselves against and web api service (sharing the same machine key as the web site).</p>
  
  <p>I basically have a basic web site with static .html files and an asp.net application with the Web Api web service. Most of the static html files should only be available to authenticated users (requests with a valid FormsAuthentication cookie issued by a /api/login route in the web api app), and these
  files are located in a 'secure' folder below the website root. The Web Api ASP.NET application is located in an 'api' folder below the website root:</p>
  
  <p>WebsiteRoot/
    api/<br>
    secure/
    login.html
    1.html
    2.html</p>
  
  <p>This works fine, and the static files like 1.html can make AJAX requests to the web api routes below the /api route. Now I want to move 1.html and 2.html inside secure/ to restrict access to them to only authenticated users.</p>
  
  <p>The web api service itself uses FormsAuthentication to restrict access to the service routes. 
  Users authenticate by making AJAX requests to /api/login (which is configured with [AllowAnnonymous]), and now I want only users authenticated this way to be granted access to the static .html files inside the secure/ folder.</p>
  
  <p>So my idea is this:</p>
  
  <p>1) Ensure that the ASP.NET pipeline handles requests to .html files.</p>
  
  <p>2) Enable forms authentication in the static web site</p>
  
  <p>3) Deny anonymous access to the websiteroot/secure folder.</p>
  
  <p>4) Ensure that the Auth cookie issued when authenticating against /api/login is also valid for the authentication mechanism on the /secure folder.</p>
  
  <p>I have tried doing this, but currently I am denied access to files inside websiteroot/secure even though the request is authenticated (it has an .ASPFORMSAUTHI cookie issued by the /api/login route in the web api app)</p>
  
  <p>Here is what I have done:
  I have 3 web.config files: 1 in WebsiteRoot, 1 in WebsiteRoot/api (the root of the web api application) and 1 in WebsiteRoot/secure</p>
  
  <p>To ensure 4), I have configured FormsAuthentication identically and used the same machoine key in both the website root and the websiteroot/api web.config files. The domin for the cookie is set to the same in both files.</p>
  
  <p>Then, to ensure 1), I have added this to the website root web.config file, to ensure that .html files (all files) are handled and authenticated by the ASP.NET pipeline:</p>
  
  <pre><code>&lt;system.webServer&gt;
      &lt;modules runAllManagedModulesForAllRequests="true"&gt;
            &lt;add  name="FormsAuthenticationModule"  type="System.Web.Security.FormsAuthenticationModule" /&gt;
            &lt;remove  name="UrlAuthorization" /&gt;
            &lt;add  name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule"  /&gt;
            &lt;remove  name="DefaultAuthentication" /&gt;
            &lt;add  name="DefaultAuthentication"  type="System.Web.Security.DefaultAuthenticationModule" /&gt;
      &lt;/modules&gt;
  &lt;/system.webServer&gt;
  </code></pre>
  
  <p>Here is the relevant stuff from the web api application web.config file located in websiteroot/api/ :</p>
  
  <pre><code>&lt;system.web&gt;
  &lt;authentication mode="Forms"&gt;
    &lt;forms name=".ASPXFORMSAUTH" protection="All" path="/" domain=".mydomain.com" timeout="7200" slidingExpiration="true" /&gt;
  &lt;/authentication&gt;
  &lt;machineKey validationKey="SAME_IN_BOTH_FILES" decryptionKey="SAME_IN_BOTH_FILES" validation="SHA1" decryption="AES" /&gt;
  &lt;roleManager enabled="true" defaultProvider="simple"&gt;
    &lt;providers&gt;
      &lt;clear /&gt;
      &lt;add name="simple" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData" /&gt;
    &lt;/providers&gt;
  &lt;/roleManager&gt;
  &lt;membership defaultProvider="simple"&gt;
    &lt;providers&gt;
      &lt;clear /&gt;
      &lt;add name="simple" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData" /&gt;
    &lt;/providers&gt;
  &lt;/membership&gt;
  ...
  </code></pre>
  
  <p></p>
  
  <p>Here is the website root web.config file located in websiteroot/ :</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;configuration&gt;
      &lt;system.web&gt;
          &lt;authentication mode="Forms"&gt;
            &lt;forms loginUrl="login.html" name=".ASPXFORMSAUTH" protection="All" domain=".mydomain.com" path="/" timeout="7200" slidingExpiration="true" /&gt;
          &lt;/authentication&gt;
          &lt;machineKey validationKey="SAME_IN_BOTH_FILES" decryptionKey="SAME_IN_BOTH_FILES" validation="SHA1" decryption="AES" /&gt;
      &lt;/system.web&gt;
              &lt;system.webServer&gt;
                  &lt;modules runAllManagedModulesForAllRequests="true"&gt;
                        &lt;add  name="FormsAuthenticationModule"  type="System.Web.Security.FormsAuthenticationModule" /&gt;
                        &lt;remove  name="UrlAuthorization" /&gt;
                        &lt;add  name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule"  /&gt;
                        &lt;remove  name="DefaultAuthentication" /&gt;
                        &lt;add  name="DefaultAuthentication"  type="System.Web.Security.DefaultAuthenticationModule" /&gt;
                  &lt;/modules&gt;
              &lt;/system.webServer&gt;
  &lt;/configuration&gt;
  </code></pre>
  
  <p>Here is the web.config file located in websiteroot/secure/ :</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;configuration&gt;
      &lt;system.web&gt;
          &lt;authorization&gt;
              &lt;deny users="?" /&gt;
          &lt;/authorization&gt;
      &lt;/system.web&gt;
  &lt;/configuration&gt;
  </code></pre>
  
  <p>Note, that if I change </p>
  
  <pre><code>&lt;deny users="?" /&gt; 
  </code></pre>
  
  <p>to </p>
  
  <pre><code>&lt;allow users="?" /&gt;  
  </code></pre>
  
  <p>Then I am granted access to the .html files inside websiteroot/secure/</p>
  
  <p>So my question are: </p>
  
  <p>1) Why are requests to /secure denied when the requests contains the .ASPFORMSAUTH cookies issued by /api/login? </p>
  
  <p>2) Are there alternative solutions as to how to make a static website where some files are restricted to users who have been authenticated against an web api service on the same site?</p>