ASP.NET WebAPI Basic Authentication always fails as 401/Unauthorized

六眼飞鱼酱① 提交于 2019-12-21 09:22:52

问题


Trying to secure my ASP.NET Web API-2 using Basic Authentication but it is always ending up with error:

401/Unauthorized
Authorization has been denied for this request.

Below are my controller and ajax request code snippet alongside the request and response headers.

BasicAuthenticationHandler.SendAsync always runs successfully up-till:

return base.SendAsync(request, cancellationToken);

Q: Then WHY it ends up as 401/unauthorized ?

If I remove [Authorize] from the controller action then it works but without any security.

Note: Because this is a cross-domain request so I have enabled CORS on server side.

My Authentication Handler

protected override System.Threading.Tasks.Task<HttpResponseMessage> 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<UserInfoModel>(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);
}

My Controller

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<Product> GetAllProducts()
{
    return products;
}
}

My AJAX Request

$.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);
    }
});

Request Headers

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

Response Headers

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

回答1:


Don't set the Principal on the Thread.CurrentPrinicipal any more. Use the Principal on the HttpRequestContext.




回答2:


In my case, following Darrels approach, I commented out the below and used his approach. It work great!... saving me hours

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


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



回答3:


Add the following to rest/resource sever and authentication server web.config

You must generate your own keys using http://www.codeproject.com/Articles/221889/How-to-Generate-Machine-Key-in-IIS



来源:https://stackoverflow.com/questions/19835665/asp-net-webapi-basic-authentication-always-fails-as-401-unauthorized

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!