Jos*_*osh 22 asp.net asp.net-mvc claims-based-identity
请求我帮助实现向经过身份验证的用户分配声明的自定义方式.成功登录后,
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
//Get the user
ApplicationUser user = UserManager.FindByEmail(model.Email);
//Ends here
ClaimsIdentity identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = true }, identity);
Run Code Online (Sandbox Code Playgroud)
我使用userId从数据存储区中获取有关用户的角色和其他信息.此后,我需要在重定向到用户仪表板之前,使用电子邮件,角色,名字,姓氏,性别等信息添加有关用户的声明.这是我尝试这样做的方式,但问题是即使在登录方法添加声明后,我也无法在_loginPartial剃刀视图中检索它
例如,当我想在登录部分显示电子邮件索赔值时,就像这样
var claims = ClaimsPrincipal.Current.Claims;
var principal = (ClaimsPrincipal)Thread.CurrentPrincipal;
var email = principal.Claims.Where(c => c.Type == ClaimTypes.Email).Select(c => c.Value).SingleOrDefault();
Run Code Online (Sandbox Code Playgroud)
它返回null.
因此,我只能在添加它们后使用相同的登录方法访问它们,但我需要能够从应用程序的任何位置访问它们.如果能够在整个申请中的任何其他地方检索这些声明,我将非常感谢.
谢谢.
Sam*_*ari 36
您必须在登录前添加您的声明,而不是之后.考虑这个例子:
public async Task<ActionResult> Login(LoginViewModel model,string returnUrl)
{
var user = UserManager.Find(model.Email, model.Password);
if(user!=null)
{
var ident = UserManager.CreateIdentity(user,
DefaultAuthenticationTypes.ApplicationCookie);
ident.AddClaims(new[] {
new Claim("MyClaimName","MyClaimValue"),
new Claim("YetAnotherClaim","YetAnotherValue"),
});
AuthenticationManager.SignIn(
new AuthenticationProperties() { IsPersistent = true },
ident);
return RedirectToLocal(returnUrl);
}
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
Run Code Online (Sandbox Code Playgroud)
现在,由于我们在登录时注入了索赔,因此我们可以随时随地访问索赔:
((ClaimsIdentity)User.Identity).FindFirst("MyClaimName");
Run Code Online (Sandbox Code Playgroud)
您也可以在ApplicationUser.GenerateUserIdentityAsync()方法中添加声明.通过在此方法中添加声明,您可以使用SignInManager.PasswordSignInAsync()方法登录用户,而无需对默认Login操作方法进行任何修改.
public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
userIdentity .AddClaims(new[] {
new Claim("MyClaimName","MyClaimValue"),
new Claim("YetAnotherClaim","YetAnotherValue"),
});
return userIdentity;
}
}
Run Code Online (Sandbox Code Playgroud)
在标识2中,这非常不同,只需创建一个声明主体工厂,然后将其连接到启动的ConfigureConfigs中,如下所示...
public class CustomClaimsPrincipalFactory : UserClaimsPrincipalFactory<IUser, IApplicationRole>
{
public CustomClaimsPrincipalFactory(UserManager<IUser> userManager, RoleManager<IApplicationRole> roleManager,
IOptions<IdentityOptions> optionsAccessor)
: base(userManager, roleManager, optionsAccessor)
{
}
public async override Task<ClaimsPrincipal> CreateAsync(IUser user)
{
var principal = await base.CreateAsync(user);
// Add your claims here
((ClaimsIdentity)principal.Identity).AddClaims(new[] { new Claim(ClaimTypes.Email, user.Email),
new Claim(ClaimTypes.Gender, user.Gender),
new Claim(ClaimTypes.GivenName, user.FirstName),
new Claim(ClaimTypes.Surname, user.LastName)
});
return principal;
}
}
Run Code Online (Sandbox Code Playgroud)
这样,您就可以在调用AddIdentity之后将其连接到ConfigureServices中。
services.AddIdentity<IUser, IApplicationRole>()
.AddDefaultTokenProviders();
// Add Custom Claims processor
services.AddScoped<IUserClaimsPrincipalFactory<IUser>, CustomClaimsPrincipalFactory>();
Run Code Online (Sandbox Code Playgroud)
这是一篇关于该主题的很好的文章...
https://www.codeguru.com/csharp/csharp/cs_misc/security/asp.net-core-and-claim-based-security.html
| 归档时间: |
|
| 查看次数: |
31994 次 |
| 最近记录: |