title: How can I add token authentication to my IIS so as to secure files in a folder?
body: <p>I have a Windows Azure WebAPI application with </p>
  
  <ul>
  <li>OWIN</li>
  <li>Oauth 2</li>
  <li>token authentication</li>
  <li>Identity 2 Framework</li>
  <li>VS2013 Update 2</li>
  <li>IIS (I am not sure which version. As I just updated everything in the stack then I assume the latest version)</li>
  </ul>
  
  <p>Before a  user is authenticated when there's a <code>&lt;script&gt;</code> in my index.html file I notice cookies sent to the server looking like this:</p>
  
  <pre><code>Accept-Language: en-US,en;q=0.8
  Cookie: .AspNet.Cookies=GWLL4LgeFkn7jDndAwf-Pk_eZAPZ5LYZugSmv- ...
  </code></pre>
  
  <p>After a user is authenticated I notice the cookies change:</p>
  
  <pre><code>Accept-Language: en-US,en;q=0.8
  Cookie: .AspNet.Cookies=OqLMSpIv2aQ8KUcw3pWdAYtPYUI_tYMl4rEYKe16N ...
  </code></pre>
  
  <p>I thought I was using token authentication so my first question is "why do the cookies get changed and why are they sent at all"?</p>
  
  <p>Once a user is authenticated then with each $http request to the server I send a header like this:</p>
  
  <pre><code>Authorization: Bearer abcdefgetc....
  </code></pre>
  
  <p>My authorization on the server works when I have WebAPI methods decorated like:</p>
  
  <pre><code>[Authorize(Roles = "Admin")]
  </code></pre>
  
  <p>Here is the <strong>main web-config</strong> that shows the security settings:</p>
  
  <pre><code>&lt;system.web&gt;
      &lt;authentication mode="None" /&gt;
      &lt;compilation debug="true" targetFramework="4.5.1" /&gt;
      &lt;httpRuntime targetFramework="4.5.1" /&gt;
  &lt;/system.web&gt;
  &lt;system.webServer&gt;
      &lt;modules&gt;
        &lt;remove name="FormsAuthenticationModule" /&gt;
      &lt;/modules&gt;
  &lt;/system.webServer&gt;
  </code></pre>
  
  <p>Now I would like to add some security to some static javascript files that I have on the server. I know how I can code it so the files can be retrieved by my client and added to the DOM in two ways. Either way is okay for me to use although I prefer the first way if when I do that way then there can be authentication happen through cookies or otherwise:</p>
  
  <p><em>With a script tag and a load</em></p>
  
  <pre><code>var el = doc.createElement("script"),
  loaded = false;
  el.onload = el.onreadystatechange = function () {
    if ((el.readyState &amp;&amp; el.readyState !== "complete" &amp;&amp; el.readyState !== "loaded") || loaded) {
      return false;
    }
    el.onload = el.onreadystatechange = null;
    loaded = true;
    // done!
  };
  el.async = true;
  el.src = path;
  document.getElementsByTagName('head')[0].insertBefore(el, head.firstChild);
  </code></pre>
  
  <p><em>With a $http call and then adding it directly to the DOM (I can supply bearer token)</em></p>
  
  <pre><code>$http({
      url: '/Bundles/admin/admin1Bundle.js',
      method: "GET"
  })
  .success(function (result) {
     var m = document.createElement('script');
     m.appendChild(document.createTextNode(result));
     document.getElementsByTagName('head')[0].appendChild(m);
  </code></pre>
  
  <p>Once added the javascript becomes available. To add security I created a web.config in the folder to protect these files and allow only users with <strong>Admin</strong> role to have access:</p>
  
  <p>Here is the <strong>folders web-config</strong> that shows the security settings:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;configuration&gt;
    &lt;system.webServer&gt;
      &lt;security&gt;
        &lt;authorization&gt;
          &lt;remove users="*" roles="" verbs="" /&gt;
          &lt;add accessType="Allow" roles="Admin" verbs='GET'/&gt;
        &lt;/authorization&gt;
      &lt;/security&gt;
    &lt;/system.webServer&gt;
  &lt;/configuration&gt;
  </code></pre>
  
  <p>When a user with the role of <strong>Admin</strong> tries to access files in the folder with a GET that a <strong>has a bearer token</strong> they get a message saying:</p>
  
  <pre><code>Most likely causes:
  •No authentication protocol (including anonymous) is selected in IIS.
  •Only integrated authentication is enabled, and a client browser was used that does not support integrated authentication.
  •Integrated authentication is enabled and the request was sent through a proxy that changed the authentication headers before they reach the Web server.
  •The Web server is not configured for anonymous access and a required authorization header was not received.
  •The "configuration/system.webServer/authorization" configuration section may be explicitly denying the user access.
  
  This error occurs when the WWW-Authenticate header sent to the Web server is not supported by the 
  server configuration. Check the authentication method for the resource, and verify which authentication 
  method the client used. The error occurs when the authentication methods are different. To determine 
  which type of authentication the client is using, check the authentication settings for the client.
  </code></pre>
  
  <p>It seems like my IIS (the version I am using on my development environment when I click Debug > Start Debugging) is using a different kind of authentication from that used by my WebAPI. Can someone explain to me:</p>
  
  <ul>
  <li>Should I be using <code>&lt;system.web&gt;</code> or <code>&lt;system.webServer&gt;</code> for the security?</li>
  <li>How can I make the IIS use the same security path as WebAPI is using when I decorate my WebAPI methods? Note that I need a way to do this with web.config as I don't have access to make changes to the IIS directly once the application is published to the cloud.</li>
  <li>I am using token authentication so why is the cookie information sent? Could I just use this cookie information to secure my javascript files from getting downloaded?</li>
  </ul>
  
  <p><strong>Notes:</strong></p>
  
  <p>Here is the way I have authentication set up in Startup.Auth.cs</p>
  
  <pre><code>        // Configure the application for OAuth based flow
          PublicClientId = "self";
          OAuthOptions = new OAuthAuthorizationServerOptions
          {
              TokenEndpointPath = new PathString("/Token"),
              Provider = new ApplicationOAuthProvider(PublicClientId),
              AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
              AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
              AllowInsecureHttp = true
          };
  
          // Enable the application to use bearer tokens to authenticate users
          app.UseOAuthBearerTokens(OAuthOptions);
  </code></pre>