La autenticación básica de ASP.NET WebAPI siempre falla como 401 / No autorizado

Intento asegurar mi ASP.NET Web API-2 utilizando la autenticación básica, pero siempre está terminando con un error:

401/Unauthorized Authorization has been denied for this request. 

A continuación, se encuentran mi controlador y un fragmento de código de solicitud ajax junto con los encabezados de solicitud y respuesta.

BasicAuthenticationHandler.SendAsync siempre se ejecuta correctamente hasta:

 return base.SendAsync(request, cancellationToken); 

P: Entonces, ¿POR QUÉ termina como 401 / no autorizado?

Si elimino [Autorizar] de la acción del controlador, entonces funciona pero sin ningún tipo de seguridad.

Nota: debido a que esta es una solicitud de dominio cruzado, he habilitado CORS en el lado del servidor.

Mi controlador de autenticación

 protected override System.Threading.Tasks.Task SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { var principal = Thread.CurrentPrincipal; if (principal.Identity.IsAuthenticated) { return base.SendAsync(request, cancellationToken); } var encryptedTicket = ExtractToken(request.Headers.Authorization); // simply returns a string if (encryptedTicket != null) { var ticket = FormsAuthentication.Decrypt(encryptedTicket); var serializer = new JavaScriptSerializer(); var user = serializer.Deserialize(ticket.UserData); if (user != null) { var identity = new GenericIdentity(user.UserName, "Basic"); Thread.CurrentPrincipal = new GenericPrincipal(identity, new string[0]); } } // Code reaches here always successfully but after this line errors Unauthorized return base.SendAsync(request, cancellationToken); } 

Mi controlador

 public class ProductController : ApiController { Product[] products = new Product[] { new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 } }; [Authorize] [Route("test/products")] [EnableCors(origins: "*", headers: "*", methods: "*")] public IEnumerable GetAllProducts() { return products; } } 

Mi solicitud de AJAX

 $.ajax({ type: "GET", url: "http://webapi.server.com/test/products", crossDomain: true, dataType: "json", contentType: "application/json; charset=utf-8", headers: { Authorization: "Basic 1234567890" }, success: function (data) { alert(data); }, error: function (err) { alert(err); } }); 

Encabezados de solicitud

 Accept application/json, text/javascript, */*; q=0.01 Accept-Encoding gzip, deflate Accept-Language en-US,en;q=0.5 Authorization Basic 1234567890 Content-Type application/json; charset=utf-8 Host webapi.server.com Origin local-pc Referer local-pc/Index.aspx User-Agent Mozilla/5.0 (Windows NT 6.2; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0 

Cabeceras de respuesta

 Access-Control-Allow-Orig... * Cache-Control no-cache Content-Length 61 Content-Type application/json; charset=utf-8 Date Thu, 07 Nov 2013 11:48:11 GMT Expires -1 Pragma no-cache Server Microsoft-IIS/8.0 X-AspNet-Version 4.0.30319 X-Powered-By ASP.NET 

No coloque el Principal en el Thread.CurrentPrinicipal más. Utilice el Principal en el HttpRequestContext.

En mi caso, siguiendo el enfoque de Darrel, comenté lo siguiente y utilicé su enfoque. ¡Funciona genial! … ahorrándome horas

 // Thread.CurrentPrincipal = PrincipalProvider // .CreatePrincipal(parsedCredentials.Username, parsedCredentials.Password); request.GetRequestContext().Principal = PrincipalProvider .CreatePrincipal(parsedCredentials.Username, parsedCredentials.Password); 

Agregue lo siguiente a rest / recurso y servidor de autenticación web.config

Debe generar sus propias claves utilizando http://www.codeproject.com/Articles/221889/How-to-Generate-Machine-Key-in-IIS