成功登录后添加声明

its*_*ohn 11 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);
   }
}
Run Code Online (Sandbox Code Playgroud)

我认为这是正确的方法,但是调用User.Identity.GetUserId()抛出异常.它似乎User.Identity没有被成功的登录更新.代替这个现实,对我来说,获取新签名用户ID的最佳方式是什么,以便我可以添加声明?

或者我这样做是错的?

tmg*_*tmg 5

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

如果您想在登录时将声明与登录用户相关联,则必须覆盖SignInAsync方法SignInManager

public override async Task SignInAsync(ApplicationUser user, bool isPersistent, bool rememberBrowser) { var userIdentity = await CreateUserIdentityAsync(user); // your code here userIdentity.AddClaim(new Claim(ClaimTypes.Gender, "male")); // AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie, DefaultAuthenticationTypes.TwoFactorCookie); if (rememberBrowser) { var rememberBrowserIdentpublic override async Task SignInAsync(ApplicationUser user, bool isPersistent, bool rememberBrowser)
{
    var userIdentity = await CreateUserIdentityAsync(user);

    // add your claims here
    userIdentity.AddClaim(new Claim(ClaimTypes.Gender, "male"));
    //

    AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie, DefaultAuthenticationTypes.TwoFactorCookie);
    if (rememberBrowser)
    {
        var rememberBrowserIdentity = AuthenticationManager.CreateTwoFactorRememberBrowserIdentity(ConvertIdToString(user.Id));
        AuthenticationManager.SignIn(new AuthenticationProperties { IsPersistent = isPersistent }, userIdentity, rememberBrowserIdentity);
    }
    else
    {
        AuthenticationManager.SignIn(new AuthenticationProperties { IsPersistent = isPersistent }, userIdentity);
    }
}
Run Code Online (Sandbox Code Playgroud)


Hun*_* Ha 5

必须在触发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;
    }
}
Run Code Online (Sandbox Code Playgroud)

登录前应用此工厂:

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