ASP.NET的WebAPI基本身份验证总是失败为401 /未经授权 [英] ASP.NET WebAPI Basic Authentication always fails as 401/Unauthorized

查看:3148
本文介绍了ASP.NET的WebAPI基本身份验证总是失败为401 /未经授权的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

试图保护我的ASP.NET Web API-2使用基本身份验证,但它总是与错误结束了:

  401 /未经授权
授权已被拒绝了这一请求。

下面是我的控制器和Ajax请求code段旁边的请求和响应头。

BasicAuthenticationHandler.SendAsync始终运行成功了耕:

 返回base.SendAsync(请求的CancellationToken);

问:那么为什么它最终为401 /未经授权

如果我从控制器动作中清除[授权],然后它的工作原理,但没有任何安全性。

注:由于这是一个跨域请求,所以我已经启用服务器端CORS

我的认证处理程序

 保护覆盖System.Threading.Tasks.Task< Htt的presponseMessage> SendAsync(HTT prequestMessage要求,System.Threading.CancellationToken的CancellationToken)
{
    VAR本金= Thread.CurrentPrincipal中;
    如果(principal.Identity.IsAuthenticated)
    {
        返回base.SendAsync(请求的CancellationToken);
    }    VAR的encryptedTicket = ExtractToken(request.Headers.Authorization); //简单地返回一个字符串
    如果(的encryptedTicket!= NULL)
    {
        VAR票= FormsAuthentication.Decrypt(encryptedTicket中);
        VAR串行=新的JavaScriptSerializer();
        VAR用户= serializer.Deserialize< UserInfoModel>(ticket.UserData);        如果(用户!= NULL)
        {
            VAR身份=新的GenericIdentity(user.UserName,基本);
            = Thread.CurrentPrincipal中新的GenericPrincipal(身份,新的字符串[0]);
        }
    }    // code到达这里总能成功,但此行之后,未经授权的错误
    返回base.SendAsync(请求的CancellationToken);
}

我的控制器

 公共类ProductController的:ApiController
{产品[] =产品新产品[]
{
    新产品{ID = 1,名称=番茄汤,类别=杂货,价格= 1}
};[授权]
[路线(测试/产品)]
[EnableCors(来源:*,标题:*,方法:*)]
公共IEnumerable的<产品与GT; GetAllProducts()
{
    回报的产品;
}
}

我的AJAX请求

  $。阿贾克斯({
    键入:GET,
    网址:http://webapi.server.com/test/products
    跨域:真实,
    数据类型:JSON
    的contentType:应用/ JSON的;字符集= UTF-8,
    标题:{授权:基本1234567890},
    成功:功能(数据){
            警报(数据);
    },
    错误:功能(错误){
            警报(ERR);
    }
});

请求头

 接受应用程序/ JSON,文本/ javascript中,* / *; Q = 0.01
接受编码gzip的,放气
接受语言恩美,恩; Q = 0.5
授权基本1234567890
内容类型应用程序/ JSON的;字符集= UTF-8
主持人webapi.server.com
产地本地PC
Referer的本地PC /的Index.aspx
用户代理的Mozilla / 5.0(Windows NT的6.2; WOW64; RV:25.0)的Gecko / 20100101火狐/ 25.0

响应头

 接入控制允许原稿... *
缓存控制无缓存
内容长度61
内容类型应用程序/ JSON的;字符集= UTF-8
日期星期四,2013年11月7日11时48分11秒GMT
过期-1
杂无缓存
服务器Microsoft-IIS / 8.0
的X ASPNET-版本4.0.30319
的X技术,通过ASP.NET


解决方案

不要设置在Thread.CurrentPrinicipal校长了。用校长的Htt的prequestContext。

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

解决方案

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

这篇关于ASP.NET的WebAPI基本身份验证总是失败为401 /未经授权的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆