我做了什么
我正在构建一个REST-ish WebAPI应用程序。我正在尝试在此处实现表单身份验证,因此客户端可以允许用户从其浏览器登录/注册/注销。我正在使用simpleMembership,用户存储在我的应用程序的simpleMembership数据库表中。作为第一步,我在AccountsController中实现了一个登录方法:
[System.Web.Http.HttpPost]
public HttpResponseMessage LogIn(LoginModel model)
{
if (ModelState.IsValid)
{
if (User.Identity.IsAuthenticated)
{
return Request.CreateResponse(HttpStatusCode.Conflict, "already logged in.");
}
if (WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
//TODO: look up by id, not by name
var userProfile = _service.GetUser(WebSecurity.GetUserId(model.UserName));
return Request.CreateResponse(HttpStatusCode.OK, userProfile);
}
else
{
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
}
}
// If we got this far, something failed
return new HttpResponseMessage(HttpStatusCode.InternalServerError);
}
问题
以下是发生的事情:
if (User.Identity.IsAuthenticated)
设置断点。else
语句中的代码被命中,但一旦返回,1)我的断点再次被击中,2)主体被设置为我的Windows身份。两者都是意料之外的,我正在试图弄清楚如何纠正它。
预期行为
配置
我认为这是一个配置问题 - 由于某种原因,在身份验证失败时,主体会自动设置为我的Windows帐户。一些与我的配置相关的细节:
<authentication mode="Forms">
<forms loginUrl="~/" timeout="2880" />
</authentication>
问题
更新1
我已经尝试注册以下处理程序:
public class PrincipalHandler : DelegatingHandler
{
protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
System.Threading.CancellationToken
cancellationToken)
{
HttpContext.Current.User = new GenericPrincipal(new GenericIdentity(string.Empty), null);
Thread.CurrentPrincipal = HttpContext.Current.User;
return await base.SendAsync(request, cancellationToken);
}
}
现在,主体永远不会设置为我的Windows身份。从POSTMan(浏览器扩展),if语句被命中两次,我得到一个弹出窗口,要求提供凭据。来自Fiddler,我按照预期获得了401 Unauthorized。
新问题
更新2
这篇文章似乎让我朝着正确的方向发展 - 在我的LoginMethod中使用Membership而不是User:
ASP.NET MVC - Set custom IIdentity or IPrincipal
将继续更新进度,但我仍然愿意接受建议/推荐。
更新3 我从未如此放松和生气 - 这里不需要自定义处理程序。我的项目属性中启用了Windows身份验证。登录和注销的工作解决方案在这里,并且“正常工作”我的会员表:
public HttpResponseMessage LogIn(LoginModel model)
{
if (ModelState.IsValid)
{
if (User.Identity.IsAuthenticated)
{
return Request.CreateResponse(HttpStatusCode.Conflict, "already logged in.");
}
if (WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
return Request.CreateResponse(HttpStatusCode.OK, "logged in successfully");
}
else
{
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
}
}
// If we got this far, something failed
return new HttpResponseMessage(HttpStatusCode.InternalServerError);
}
public HttpResponseMessage LogOut()
{
if (User.Identity.IsAuthenticated)
{
WebSecurity.Logout();
return Request.CreateResponse(HttpStatusCode.OK, "logged out successfully.");
}
return Request.CreateResponse(HttpStatusCode.Conflict, "already done.");
}
答案 0 :(得分:4)
您使用IIS Express进行开发吗?如果是这样,请在Visual Studio中单击您的项目并检查属性窗口。这里有一个Windows身份验证选项,我认为默认情况下启用。在这里也禁用它。