我正在使用AngularJS和ASP.NET Identity 2处理单页应用程序。我将用户登录并设置了cookie;但是,当我在同一请求中检查用户的身份时,它会将其显示为空白,并且IsAuthenticated为false。但是,这些都会在后续请求中填充。我希望无论用户是否在同一请求中登录,都会向UI发回。这可能吗?
按要求编写代码(AngularJS将AJAX发布到WebAPI控制器登录方法中)
[HttpPost]
[AllowAnonymous]
[Route("Login")]
public async Task<IHttpActionResult> Login(LoginModel loginModel)
{
var result = await _securityService.Login(loginModel.UserName, loginModel.Password);
if (!result)
{
ModelState.AddModelError("errorMessage", "Invalid username or password.");
return BadRequest(ModelState);
}
return Ok();
}
public async Task<bool> Login(string userName, string password, bool persistCookie = false)
{
var user = await _userManager.FindAsync(userName, password);
if (user != null)
await SignInAsync(user, persistCookie);
else
return false;
return true;
}
private async Task SignInAsync(ApplicationUser user, bool isPersistent)
{
_authenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
_authenticationManager.SignIn(new AuthenticationProperties() {IsPersistent = isPersistent}, await CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie));
}
public Task<ClaimsIdentity> CreateIdentity(ApplicationUser user, string authenticationType)
{
return _userManager.CreateIdentityAsync(user, authenticationType);
}
答案 0 :(得分:5)
在下一个请求之前,您不会获得已登录的身份,因为对SignIn的调用是导致在响应上设置cookie的原因。该cookie将在后续请求中变为身份,但是为时已晚,无法更改当前请求的身份。
答案 1 :(得分:2)
使用Owin身份验证时,AuthenticationManager.SignIn()
方法几乎不向cookie处理程序发送消息,以便在Cookie处理程序在Web API控制器之后处理请求时设置cookie(请参阅我的博文{{3}有关详情)。
但如果登录成功,则Login
方法会返回true
,如果没有,则false
会返回Login
,因此您可以在Login()
操作中使用该信息来发回信息。如果您不仅想知道登录是否成功,而且还想要实际身份,则可以更改null
以在成功登录时返回用户,如果失败则返回{{1}}。
答案 2 :(得分:0)
我将用户登录并设置了cookie;但是,当我在同一请求中检查用户的身份时,它会将其显示为空白,并且IsAuthenticated为false。
This is just a lack of knowledge on your part about how the ASP.Net pipeline works
发生了相当大的事件管道。我非常确定MVC在ProcessRequest方法中运行。此方法位于AuthenticateRequest事件和PostAuthenticateRequest事件之后。这意味着在ProcessRequest方法期间永远不能更新整个ASP.Net身份验证框架。这就是为什么您会看到几乎所有系统都在之后进行重定向,以便下一个请求具有所有身份验证(IIdentity,IPrincipal,IsAuthenticated等)。
我希望无论用户是否在同一请求中登录,都会向UI发回。这可能吗?
代码怎么能不能?第一个请求是否对它们进行身份验证,无论代码是什么,都知道它们是否经过身份验证。
答案 3 :(得分:0)
我希望无论用户是否在同一请求中登录,都会向UI发回。这可能吗?
是。正如其他回复中所述,你可以。
我只是想在你处于相同的请求时但是在SignIn发生的上下文之外的情况下覆盖这个案例。
通过Owin,你可以使用类似这种扩展方法的东西:
/// <summary>
/// Check if the user was authenticated in the current request, or in a previous one
/// </summary>
public static bool IsUserAuthenticated(this IOwinContext context)
{
if (context.Request.User.Identity.IsAuthenticated)
return true;
if (null != context.Authentication.AuthenticationResponseGrant && null != context.Authentication.AuthenticationResponseGrant.Identity)
{
return context.Authentication.AuthenticationResponseGrant.Identity.IsAuthenticated;
}
return false;
}