Mic*_*han 6 c# asp.net asp.net-mvc asp.net-web-api asp.net-identity
我正在使用ASP.NET MVC 5和WebApi 2并尝试使用重定向进行Ajax登录(如果成功).
对于身份验证,我使用默认为新的ASP.NET MVC项目提供的ASP.NET标识库.
我得到了一切正常,使用MVC 5一切都很好.但对于我的生活,我无法让标准的MVC控制器返回简单的JSON.(它包装了我想要在父对象中返回的JSON)是的我可以在客户端修复此问题,但对我来说这是hacky.
我似乎更好的另一个选择是使用WebApi,它按照我的期望返回对象(只是我的JSON作为正文).但我遇到的问题是ASP.NET身份SignInManager不发送.ASPNet.Identitycookie,除非我返回一个ActionResult.
下面是我的WebApi控制器,它返回正确的预期最小JSON但不发送Set-Cookie命令,因此任何重定向都会将用户视为未登录.
[Authorize]
public class AccountController : ApiController
{
public AccountController(IApplicationSignInManager signInManager)
{
SignInManager = signInManager;
}
public IApplicationSignInManager SignInManager {....}
//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[NgValidateAntiForgeryToken]
public async Task<HttpResponseMessage> Login(LoginViewModel model)
{
// Temporarily using Dynamic
dynamic res = new ExpandoObject();
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, change to shouldLockout: true
var status = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
res.status = status.ToString();
return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(res))
};
}
}
Run Code Online (Sandbox Code Playgroud)
返回以下Json但没有cookie:
{"status":"Success"}
Run Code Online (Sandbox Code Playgroud)
如果我将其更改为返回ActionResult而不是HttpResponseMessage,则会发送Set-Cookie命令,但Json将包含在其他属性中.
public async Task<ActionResult> Login(LoginViewModel model)
{
// Temporarily using Dynamic
dynamic res = new ExpandoObject();
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, change to shouldLockout: true
var status = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
res.status = status.ToString();
return new JsonResult{Data = res};
}
Run Code Online (Sandbox Code Playgroud)
哪个返回cookie但包裹了Json:
{"contentEncoding":null,"contentType":null,"data":{"status":"Success"},"jsonRequestBehavior":1,"maxJsonLength":null,"recursionLimit":null}
Run Code Online (Sandbox Code Playgroud)
现在我猜他正在发生,因为SignInManager可能正在将cookie分配给之前生成的HttpContext.Current.Response对象.当我返回一个JsonResult时,ASP.NET将此结果固定到HttpContext.Current.Response并发送到客户端,因此具有cookie.
但是当我返回一个HttpResponseMessage时,ASP.NET返回新创建的HttpResponse,它没有SignInManager cookie.我认为这是对的吗?
编辑1:由@David Tansey建议我尝试了以下,仍然没有设置cookie但返回正确的Json
public async Task<IHttpActionResult> Login(LoginViewModel model)
{
var status = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
return Json(new {status = status.ToString()});
}
Run Code Online (Sandbox Code Playgroud)
返回正确的json,但没有cookie:
{"status":"Success"}
Run Code Online (Sandbox Code Playgroud)
FIX:在@David Tansey指出使用匿名类型new {}之后,我决定尝试一下.以下两种方法都有效
MVC
必须返回一个ActionResult/JsonResult,除了Data之外的所有字段都为null,并且必须返回一个Anonymous类型而不是动态,ExpandoObject()因为动态对象导致序列化程序膨胀返回的Json
[HttpPost]
[AllowAnonymous]
[NgValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model)
{
var status = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
//return Json(new {status = status.ToString()});
// OR
return new JsonResult { Data = new { status = status.ToString() } };
}
Run Code Online (Sandbox Code Playgroud)
WebApi 2
不得不将返回类型更改为对象,将其序列化为Json,并设置cookie.返回HttpResponseMessage导致SignInManager设置为丢失的cookie我猜它是使用新返回的响应对象的开始.
[HttpPost]
[AllowAnonymous]
[NgValidateAntiForgeryToken]
public async Task<object> Login(LoginViewModel model)
{
var status = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
return new {status = status.ToString()};
}
Run Code Online (Sandbox Code Playgroud)
也许问题在于您正在尝试使用 cookie,而您应该使用令牌……这就是您遇到 hackyness 问题的原因。
请参阅本指南以了解如何设置基于令牌的身份验证:http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity /
(通常我会发布相关代码,但设置它需要相当多的内容。)
| 归档时间: |
|
| 查看次数: |
3850 次 |
| 最近记录: |