成功登录后添加声明

时间:2015-06-19 20:06:29

标签: c# asp.net-mvc asp.net-identity

我需要在用户成功登录后添加对用户身份的声明。这是我认为需要发生的地方:

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

   var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false);
   switch (result)
   {
      case SignInStatus.Success:
         UserManager.AddClaim(User.Identity.GetUserId(), new Claim("MyClaim", myClaimValue));
         return RedirectToLocal(returnUrl);
      case SignInStatus.LockedOut:
         return View("Lockout");
      case SignInStatus.RequiresVerification:
         return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
      case SignInStatus.Failure:
      default:
         ModelState.AddModelError("", "Invalid login attempt.");
         return View(model);
   }
}

我认为这是正确的方法,但对User.Identity.GetUserId()的调用会引发异常。看起来User.Identity没有被成功登录更新。代替这个现实,我最好的方式是获得新签名的用户ID,以便我可以添加声明吗?

或者我这样做错了吗?

2 个答案:

答案 0 :(得分:4)

必须在触发SignInManager.PasswordSignInAsync之前设置其他声明。这可以通过自定义ClaimsIdentityFactory来完成:

public class ApplicationClaimsIdentityFactory : ClaimsIdentityFactory<ApplicationUser>
{
    // This claim value is taken from Login View
    public static readonly string MyClaimKey = "app:MyClaimKey";
    public string MyClaimValue { get; set; }

    public async override Task<ClaimsIdentity> CreateAsync(UserManager<ApplicationUser, string> manager, ApplicationUser user, string authenticationType)
    {
        var identity = await base.CreateAsync(manager, user, authenticationType);
        identity.AddClaim(new Claim(MyClaimKey, MyClaimValue));
        return identity;
    }
}

在登录步骤之前应用此工厂:

UserManager.ClaimsIdentityFactory = new ApplicationClaimsIdentityFactory() 
        { 
            MyClaimValue = loginModel.MyClaimValue
        };
var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false);

答案 1 :(得分:3)

这会将声明存储到数据库UserManager.AddClaim(User.Identity.GetUserId(), new Claim("MyClaim", myClaimValue));

如果您只想在登录时与登录用户关联声明,则必须覆盖SignInAsync的{​​{1}}方法

SignInManager