title: Web API 2 use Windows Authentication for public users
body: <p>How do I use Windows Authentication in WEB API for internal users who will also be on the public network? The REST API will be public facing and will need to authenticate intranet users as well as internet users. Basically, anybody not on Active Directory won't be able to access it and one more AD groups will be authorized.</p>
  
  <p>The REST service at the moment has a security filter to validate token using attribute filter.</p>
  
  <pre><code>public class RestAuthorizeAttribute : AuthorizeAttribute
  {
      private const string SecurityToken = "token";
  
      public override void OnAuthorization(HttpActionContext actionContext)
      {
          if (Authorize(actionContext))
          {
              return;
          }
  
          HandleUnauthorizedRequest(actionContext);
      }
  
  
      private bool Authorize(HttpActionContext actionContext)
      {
          try
          {
              HttpRequestMessage request = actionContext.Request;
  
              //Extract Token from the Request. This will work for all.
              // E.g \api\Facilitiles\Token\298374u23lknndsjlkfds==
              //      \api\Ward\123\Token\298374u23lknndsjlkfds==
              string path = request.RequestUri.LocalPath;
  
              int indexOfToken = path.IndexOf(SecurityToken) + SecurityToken.Length + 1; 
  
              string token = path.Substring(indexOfToken);
  
              bool isValid = SecurityManager.IsTokenValid(token, IpResolver.GetIp(request),request.Headers.UserAgent.ToString());
              return isValid;
          }
          catch (Exception ex)
          {
              string av = ex.Message;
              return false;
          }
      }
  }
  </code></pre>
  
  <p>This is then applied to specific controllers like this:</p>
  
  <pre><code>[RestAuthorize]
  [RoutePrefix("api/patient")]
  [EnableCors(origins: "*", headers: "*", methods: "*")]
  public class PatientDetailsController : ApiController
  {
  
      PatientDetailsRetriever _patientDetailsRetriever;
  
      // GET: api/patient/meds/personId/{personId}/token/{token}
      [Route("meds/personId/{personId}/token/{token}")]
      [HttpGet]
      public HttpResponseMessage GetMeds(Int64 personId, string token)
      {
          List&lt;Medication&gt; meds;
  .....
  </code></pre>
  
  <p>The client generates the token which includes <strong>username, password and domain</strong> and among other things.</p>
  
  <p>Enabling Windows Authentication in IIS (web.config) will be enough to validate local users. But how does this work when the user is outside the network and sends in the credentials?</p>