添加自定义用户声明的适当位置
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
方法。在这一刻,我变得不清楚了。乍一看,有两种类似的生成用户身份的方法:
- 在AppUserclass里面,以
usermanager
class为参数-public async Task<ClaimsIdentity> GenerateUserIdentityAsync(AppUserManager manager)
- 内部 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);
}
}
有一个用户 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
方法。在这一刻,我变得不清楚了。乍一看,有两种类似的生成用户身份的方法:
- 在AppUserclass里面,以
usermanager
class为参数-public async Task<ClaimsIdentity> GenerateUserIdentityAsync(AppUserManager manager)
- 内部 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);
}
}