未在登录请求中设置ASP.NET标识

che*_*ica 6 asp.net asp.net-mvc asp.net-identity-2

我正在使用ASP.NET身份和a ClaimsIdentity来验证我的用户.对用户进行身份验证时,该属性User.Identity包含一个ClaimsIdentity实例.

但是,在登录请求期间不是这种情况:

    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, false, shouldLockout: false);
        switch (result)
        {
            case SignInStatus.Success:
                var identity = User.Identity;

------------>   // identity is of type WindowsIdentity  <------------

                return RedirectToLocal(returnUrl);
Run Code Online (Sandbox Code Playgroud)

如您所见,即使登录成功,该属性User.Identity尚未设置为ClaimsIdentity实例.我认为这是合理的,这意味着SignInManager不会更新属性,所以我们必须等到下一个请求才能看到登录结果.

但是,我必须在方法之后执行其他逻辑PasswordSignInAsync,因此我需要一种方法来获取switch语句ClaimsIdentity.Success分支中的实例.

在检查SignInManager调试器时,我看到它是类型的Microsoft.Owin.Security.AuthenticationManager,它具有SignInEntry.Item1包含ClaimsIdentity我正在寻找的属性.

但是,类型Microsoft.Owin.Security.AuthenticationManager不公开,所以唯一的方法似乎是使用反射的黑客.

有更好的方法吗?

Aug*_*eto 7

我同意PasswordSignInAsync不会将用户实例作为out参数返回太糟糕了.如果您查看源代码,您可以看到它用于this.UserManager.FindByNameAsync(userName)通过userName查找用户,然后用于this.UserManager.CheckPasswordAsync(user, password)验证密码,但用户存储在本地变量中.

我认为这应该被提议作为SignInManager类的改进.

一种可能(且效率低下)的解决方法是再次查询用户,然后以与SignInManager.SignInAsync相同的方式创建声明标识yourselft:

        ApplicationUser user = await UserManager.FindByNameAsync(model.Email);
        ClaimsIdentity claimsIdentity = await SignInManager.CreateUserIdentityAsync(user);
Run Code Online (Sandbox Code Playgroud)


Phi*_*hil 5

身份通过AuthenticationResponseGrant属性公开:

ClaimsIdentity identity = SignInManager.AuthenticationManager.AuthenticationResponseGrant.Identity;
Run Code Online (Sandbox Code Playgroud)