简体   繁体   English

ASP.NET标识不会更新同一请求的标识信息

[英]ASP.NET Identity doesn't update Identity information on same request

I am working on a single page application using AngularJS and ASP.NET Identity 2. I log the user in and the cookie is set; 我正在使用AngularJS和ASP.NET Identity 2处理单页应用程序。我将用户登录并设置了cookie; however, when I check the Identity of the user on the same request, it shows it as blank and IsAuthenticated is false. 但是,当我在同一请求中检查用户的身份时,它会将其显示为空白,并且IsAuthenticated为false。 However, these are populated on subsequent requests. 但是,这些都会在后续请求中填充。 I was hoping to send back to the UI whether or not the user was logged in on the same request. 我希望无论用户是否在同一请求中登录,都会向UI发回。 Is this possible? 这可能吗?

Code as requested (AngularJS makes AJAX post into WebAPI controller Login method) 代码按要求(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);
}

You won't get a signed in identity until the next request because the call to SignIn is what's causing a cookie to be set on the response. 在下一个请求之前,您不会获得已签名的身份,因为对SignIn的调用是导致在响应上设置cookie的原因。 That cookie will turn into the identity on subsequent requests, but its too late to change your current request's identity. 该cookie将在后续请求中变为身份,但是为时已晚,无法更改当前请求的身份。

When using Owin authentication, the AuthenticationManager.SignIn() method barely sends a message to the cookie handler to set a cookie when the cookie handler gets to handle the request after the Web API Controller (see my blog post Understanding the Owin External Authentication Pipeline for details). 使用Owin身份验证时, AuthenticationManager.SignIn()方法几乎不向cookie处理程序发送消息,以便在cookie处理程序在Web API控制器之后处理请求时设置cookie(请参阅我的博客文章了解Owin外部身份验证管道细节)。

But the Login method returns true if the login was successful and false if not, so you can use that information in the Login action to send back information. 但是如果登录成功,则Login方法返回true否则返回false ,因此您可以在Login操作中使用该信息发送回信息。 If you don't only want to know if the login succeeded or not, but also want the actual identity you can change Login() to return the user in case of successful login and null if failed. 如果您不仅想知道登录是否成功,而且还想要实际身份,则可以更改Login()以在成功登录时返回用户,如果失败则返回null

I log the user in and the cookie is set; 我将用户登录并设置了cookie; however, when I check the Identity of the user on the same request, it shows it as blank and IsAuthenticated is false. 但是,当我在同一请求中检查用户的身份时,它会将其显示为空白,并且IsAuthenticated为false。

This is just a lack of knowledge on your part about how the ASP.Net pipeline works . 这只是缺乏关于ASP.Net管道如何工作的知识

There is a fairly large pipeline of events that occur. 发生了相当大的事件管道。 I'm pretty sure MVC runs in the ProcessRequest method. 我很确定MVC在ProcessRequest方法中运行。 This method is after the AuthenticateRequest event and the PostAuthenticateRequest event. 此方法位于AuthenticateRequest事件和PostAuthenticateRequest事件之后。 This means that the entire ASP.Net authentication framework can never be updated during the ProcessRequest method. 这意味着在ProcessRequest方法期间永远不能更新整个ASP.Net身份验证框架 This is why you'll see almost all system do a redirect afterwards, so that the next request has all the authentication (IIdentity, IPrincipal, IsAuthenticated, etc). 这就是为什么你会看到几乎所有系统都在之后进行重定向,以便下一个请求具有所有身份验证(IIdentity,IPrincipal,IsAuthenticated等)。

I was hoping to send back to the UI whether or not the user was logged in on the same request. 我希望无论用户是否在同一请求中登录,都会向UI发回。 Is this possible? 这可能吗?

How could the code not be able to? 代码怎么能不能? The first request either authenticates them or not, whatever code is doing that knows if they are authenticated. 第一个请求是否对它们进行身份验证,无论代码是什么,都知道它们是否经过身份验证。

I was hoping to send back to the UI whether or not the user was logged in on the same request. 我希望无论用户是否在同一请求中登录,都会向UI发回。 Is this possible? 这可能吗?

Yes. 是。 As said in other responses, you can. 正如其他回复中所说,你可以。

I just want to cover the case when you are in the same request but outside the context where the SignIn took place. 我只是想在你处于相同的请求时但是在SignIn发生的上下文之外的情况下覆盖这个案例。

Through Owin, you could use something like this extension method: 通过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;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM