![](/img/trans.png)
[英]ASP.NET WebAPI Basic Authentication always fails as 401/Unauthorized
[英]ASP.NET WebApi FormsAuthentication 401 (Unauthorized) issue
我一直在学习授权在ASP.Net WebApi中的工作方式,并且在另一篇文章( ASP.NET Web API身份验证 )中遇到了达林·迪米特洛夫(Darin Dimitrov)的回答,我需要一些帮助来理解为什么我会收到401。
按照Darin的代码,我创建了一个WebApi项目并添加了以下控制器和模型:
AccountController.cs
using System.Web.Http;
using System.Web.Security;
using AuthTest.Models;
namespace AuthTest.Controllers
{
public class AccountController : ApiController
{
public bool Post(LogOnModel model)
{
if (model.Username == "john" && model.Password == "secret")
{
FormsAuthentication.SetAuthCookie(model.Username, false);
return true;
}
return false;
}
}
}
UsersController.cs
using System.Web.Http;
namespace AuthTest.Controllers
{
[Authorize]
public class UsersController : ApiController
{
public string Get()
{
return "This is top secret material that only authorized users can see";
}
}
}
LogOnModel.cs
namespace AuthTest.Models
{
public class LogOnModel
{
public string Username { get; set; }
public string Password { get; set; }
}
}
我创建了一个带有两个按钮和一个标签的Web窗体应用程序,用于测试。
Default.aspx.cs
using System;
using System.Net.Http;
using System.Threading;
namespace AuthTestWebForms
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void ButtonAuthorizeClick(object sender, EventArgs e)
{
using (var httpClient = new HttpClient())
{
var response = httpClient.PostAsJsonAsync(
"http://localhost/authtest/api/account",
new { username = "john", password = "secret" },
CancellationToken.None
).Result;
response.EnsureSuccessStatusCode();
bool success = response.Content.ReadAsAsync<bool>().Result;
if (success)
{
//LabelResponse.Text = @"Credentials provided";
var secret = httpClient.GetStringAsync("http://localhost/authtest/api/users");
LabelResponse.Text = secret.Result;
}
else
{
LabelResponse.Text = @"Sorry, you provided the wrong credentials";
}
}
}
protected void ButtonTestAuthClick(object sender, EventArgs e)
{
using (var httpClient = new HttpClient())
{
var secret = httpClient.GetStringAsync("http://localhost/authtest/api/users");
LabelResponse.Text = secret.Result;
}
}
}
}
当我单击按钮并运行ButtonAuthorizeClick()时,它为Account触发控制器,然后为Users触发控制器,一切正常。
如果再单击ButtonTestAuthClick(),则会收到401(未经授权)错误。
当我在Chrome或FireFox中寻找ASPXAUTH cookie时,没有看到它,因此我不确定100%为什么ButtonAuthorizeClick()可以工作,以及我需要做什么来使ButtonTestAuthClick()起作用。
感谢您的帮助,任何人都可以抛弃我。
我遇到了类似的问题,虽然不是通过Web窗体客户端页面,而是通过JavaScript和AJAX调用。 原来我已将身份验证模式留在web.config中的“无”位置。 显然,为了使FormsAuthentication.SetAuthCookie()方法生效,您必须在此处打开Forms Authentication。
<authentication mode="Forms" />
一旦我纠正了这一疏忽,一切都会开始正常。 :-)
您正在调用带有身份验证的Web API。 为什么不通过ajax不对客户端的用户进行身份验证?
这里的问题是每次您通过HttpClient向Web api发送请求时,它实际上是服务器处理的新Web请求。 所有cookie信息都不会保留在当前请求中。 为了支持这种情况,您需要自己处理cookie。
例如:如果响应中包含Cookie ASPXAUTH,则将其设置为ButtonAuthorizeClick方法中的asp.net标头。 将cookie ASPXAUTH设置为HttpRequestMessage并由HttpClient发送。
Web API最近添加了对使用HttpServer来创建进程内服务器的支持,并且可以将请求直接发送到当前进程中的当前消息处理程序。 因此,您可以编写如下代码:
HttpClient c = new HttpClient(new HttpServer(GlobalConfiguration.DefaultHandler));
c.GetStringAsync("http://localhost/api/Values").Wait();
要将请求发送到进程内,以便在Web api操作中设置的cookie标头仍将在当前请求的管道中。 签入似乎不在RTM版本中。 您可以尝试每晚进行构建http://aspnetwebstack.codeplex.com/discussions/353867 。
尽管已经晚了,但ButtonTestAuthClick中的客户端不是浏览器。 这是httpClient对象。 因此,您需要以编程方式设置从其他按钮生成的cookie。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.