登录托管的 Blazor Wasm 应用程序时如何在令牌中附加声明?
How to attach claims in the token when logging in to a hosted Blazor Wasm app?
我创建了一个具有身份的托管 Blazor Wasm。我创建了一个用户。我还添加了一些声明。
var adminClaims = new List<Claim>
{
new Claim(ClaimTypes.Role, RoleEnums.Admin),
new Claim(CustomClaimTypes.TenantUrl, viewModel.InstitutionUrl)
};
await _userManager.AddClaimsAsync(userCreateresult.User, adminClaims);
在上面的代码运行之后,我可以验证2个声明已经添加到AspNetUserClaims table.
但是,当我 运行 应用程序时,下面的代码不起作用,即 HTML 的部分没有显示。
<AuthorizeView Roles="Admin">
<Authorized>
<li class="nav-item px-3">
<NavLink class="nav-link" href="counter">
<span class="oi oi-plus" aria-hidden="true"></span> Counter
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="fetchdata">
<span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
</NavLink>
</li>
</Authorized>
</AuthorizeView>
我尝试按照 the documentation 中的建议添加,但没有成功。
查看 /Server/Areas/Identity/Pages/Account/Login.cshtml.cs
中用户登录的代码时,我看不到令牌的创建位置。
if (ModelState.IsValid)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);
if (result.Succeeded)
{
_logger.LogInformation("User logged in.");
return LocalRedirect(returnUrl);
}
//more code here...
}
如何做才能在用户登录时发送的令牌包含所有 his/her 声明。
感谢您的帮助。
我在 Udemy 上 Felipe Gavilan's course 找到了解决方案。
创建实现 IProfileService
的 class
public class IdentityProfileService : IProfileService
{
private readonly IUserClaimsPrincipalFactory<ApplicationUser> claimsFactory;
private readonly UserManager<ApplicationUser> userManager;
public IdentityProfileService(
IUserClaimsPrincipalFactory<ApplicationUser> claimsFactory,
UserManager<ApplicationUser> userManager)
{
this.claimsFactory = claimsFactory;
this.userManager = userManager;
}
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
var userId = context.Subject.GetSubjectId();
var user = await userManager.FindByIdAsync(userId);
var claimsPrincipal = await claimsFactory.CreateAsync(user);
var claims = claimsPrincipal.Claims.ToList();
var claimsFromDb = await userManager.GetClaimsAsync(user);
var mappedClaims = new List<Claim>();
foreach (var claim in claimsFromDb)
{
if (claim.Type == ClaimTypes.Role)
mappedClaims.Add(new Claim(JwtClaimTypes.Role, claim.Value));
else
mappedClaims.Add(claim);
}
claims.AddRange(mappedClaims);
context.IssuedClaims = claims;
}
public async Task IsActiveAsync(IsActiveContext context)
{
var userId = context.Subject.GetSubjectId();
var user = await userManager.FindByIdAsync(userId);
context.IsActive = user != null;
}
}
然后注册服务
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>()
.AddProfileService<IdentityProfileService>(); //adding this line.
就是这样。现在我得到嵌入 JWT 令牌中的声明。
我创建了一个具有身份的托管 Blazor Wasm。我创建了一个用户。我还添加了一些声明。
var adminClaims = new List<Claim>
{
new Claim(ClaimTypes.Role, RoleEnums.Admin),
new Claim(CustomClaimTypes.TenantUrl, viewModel.InstitutionUrl)
};
await _userManager.AddClaimsAsync(userCreateresult.User, adminClaims);
在上面的代码运行之后,我可以验证2个声明已经添加到AspNetUserClaims table.
但是,当我 运行 应用程序时,下面的代码不起作用,即 HTML 的部分没有显示。
<AuthorizeView Roles="Admin">
<Authorized>
<li class="nav-item px-3">
<NavLink class="nav-link" href="counter">
<span class="oi oi-plus" aria-hidden="true"></span> Counter
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="fetchdata">
<span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
</NavLink>
</li>
</Authorized>
</AuthorizeView>
我尝试按照 the documentation 中的建议添加,但没有成功。
查看 /Server/Areas/Identity/Pages/Account/Login.cshtml.cs
中用户登录的代码时,我看不到令牌的创建位置。
if (ModelState.IsValid)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);
if (result.Succeeded)
{
_logger.LogInformation("User logged in.");
return LocalRedirect(returnUrl);
}
//more code here...
}
如何做才能在用户登录时发送的令牌包含所有 his/her 声明。
感谢您的帮助。
我在 Udemy 上 Felipe Gavilan's course 找到了解决方案。
创建实现 IProfileService
的 classpublic class IdentityProfileService : IProfileService { private readonly IUserClaimsPrincipalFactory<ApplicationUser> claimsFactory; private readonly UserManager<ApplicationUser> userManager; public IdentityProfileService( IUserClaimsPrincipalFactory<ApplicationUser> claimsFactory, UserManager<ApplicationUser> userManager) { this.claimsFactory = claimsFactory; this.userManager = userManager; } public async Task GetProfileDataAsync(ProfileDataRequestContext context) { var userId = context.Subject.GetSubjectId(); var user = await userManager.FindByIdAsync(userId); var claimsPrincipal = await claimsFactory.CreateAsync(user); var claims = claimsPrincipal.Claims.ToList(); var claimsFromDb = await userManager.GetClaimsAsync(user); var mappedClaims = new List<Claim>(); foreach (var claim in claimsFromDb) { if (claim.Type == ClaimTypes.Role) mappedClaims.Add(new Claim(JwtClaimTypes.Role, claim.Value)); else mappedClaims.Add(claim); } claims.AddRange(mappedClaims); context.IssuedClaims = claims; } public async Task IsActiveAsync(IsActiveContext context) { var userId = context.Subject.GetSubjectId(); var user = await userManager.FindByIdAsync(userId); context.IsActive = user != null; } }
然后注册服务
services.AddIdentityServer() .AddApiAuthorization<ApplicationUser, ApplicationDbContext>() .AddProfileService<IdentityProfileService>(); //adding this line.
就是这样。现在我得到嵌入 JWT 令牌中的声明。