我正在构建一个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)上设置一个断点.
>使用像POSTMan或Fiddler这样的东西,我尝试使用一些虚假凭据登录.
>我按照预期点击断点并获取IsAuthenticated的“False”.
>我转到下一个“if”,并且尝试LogIn失败,正如预期的那样.
> else语句中的代码被命中,但是一旦返回,1)我的断点再次被击中,2)主体设置为我的Windows标识.两者都是意想不到的,我正在试图找出如何纠正它.
预期行为
>该方法只返回401未经授权,因为虚拟用户不存在于我的应用程序的数据库中.
组态
我认为这是一个配置问题 – 由于身份验证失败的原因,主体会自动设置为我的Windows帐户.与我的配置有关的一些细节:
<authentication mode="Forms"> <forms loginUrl="~/" timeout="2880" /> </authentication>
>我没有在应用程序中的任何地方启用Windows身份验证.我的web.config在上面^
>使用IISManager我已禁用匿名身份验证
>在我的applicationhost.config我已禁用Windows和匿名身份验证
问题
>为什么断点被击中两次,而不是LogIn方法刚刚返回Unauthorized,因为最后一个“else”被击中?
>为什么我的Windows凭据被使用在这个意外和不期望的“环回”?
>如何防止这种情况发生?要么:
>我需要使用MessageHandler来设置主体吗?如果是这样,这样会影响[Authenticate]和IsAuthenticated?任何例子?
更新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未经授权.
新问题
>如何根据回应cookie中的内容设置校长,并根据我的应用程序的简单会员资格表进行身份验证?
更新2
这个帖子似乎正在让我在正确的方向 – 在我的LoginMethod中使用成员资格而不是用户:
ASP.NET MVC – Set custom IIdentity or IPrincipal
将继续更新进度,但我仍然乐意提出建议/建议.
更新3
我从来没有同时缓解和生气 – 在这里不需要定制的处理程序.在我的项目属性中启用Windows auth.登录和注销的工作解决方案在这里,“正常工作”与我的会员表:
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,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."); }