添加自定义用户声明的适当位置

Proper place for adding custom user claims

有一个用户 class,它有一个名为 "Avatar" 的字段,其中存储了他的个人资料图片的路径。我想在部分视图内的 header 中显示它。所以我决定添加对用户身份的声明。我把这行代码放在我的 IdentityConfig.cs class:

 public override Task<ClaimsIdentity> CreateUserIdentityAsync(AppUser user)
        {
            if(!System.String.IsNullOrEmpty(user.Avatar))
                user.Claims.Add(new AppUserClaim() { ClaimType = "avatar", ClaimValue = user.Avatar});

            return user.GenerateUserIdentityAsync((AppUserManager)UserManager);
        }

但是有一个问题:一段时间后(大约1小时)这个Claim就消失了,而且没有显示头像。我发现,asp.net identity 框架每 30 分钟(默认)重新生成一次用户身份。根据这个:

 regenerateIdentityCallback: (manager, user) =>
                            user.GenerateUserIdentityAsync(manager)

它调用用户 class 的 GenerateUserIdentityAsync 方法。在这一刻,我变得不清楚了。乍一看,有两种类似的生成用户身份的方法:

  1. AppUserclass里面,以usermanagerclass为参数-public async Task<ClaimsIdentity> GenerateUserIdentityAsync(AppUserManager manager)
  2. 内部 SignInManager- public override Task<ClaimsIdentity> CreateUserIdentityAsync(AppUser user)

这样做的目的是什么?每种方法都在哪里使用?我应该使用哪一个来添加自定义用户声明?

我已经稍微重构了一个标准 ASP.NET MVC 项目,所以我不再重复添加声明的代码。

Startup.Auth.cs:

public void ConfigureAuth(IAppBuilder app, Container container)
{
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        Provider = new CookieAuthenticationProvider
        {
            OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, User>(
                validateInterval: TimeSpan.FromMinutes(30),
                regenerateIdentity: (manager, user) => IdentityHelper.GenerateUserIdentityAsync(user, manager))
        }
    });
}

然后我做了一个静态辅助方法来生成身份:

public async Task<ClaimsIdentity> GenerateUserIdentityAsync(User user, UserManager<User> manager)
{
    var userIdentity = await manager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie).ConfigureAwait(false);

    userIdentity.AddClaim(new Claim("Key", "Value"));

    return userIdentity;
}

现在您将能够从您的 SignInManager.

重用这个助手
public class ApplicationSignInManager : SignInManager<User, string>
{
    public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager)
        : base(userManager, authenticationManager)
    {
    }

    public override Task<ClaimsIdentity> CreateUserIdentityAsync(User user)
    {
        return IdentityHelper.GenerateUserIdentityHelperAsync(user, (ApplicationUserManager)UserManager);
    }
}