ClaimsIdentity id = new ClaimsIdentity();
id.AddClaim(new Claim("MyNewClaim", "bla"));
context.HttpContext.User.AddIdentity(id);
嗨@Ed Williams,
通过使用上面的代码,新的声明将添加到 HttpContext 中,它将在处理单个请求时存储数据。处理请求后,集合的内容将被丢弃。
要将声明存储在 AspNetUserClaims 表中,我们可以使用UserManager.AddClaimAsync() 方法将指定的声明添加到用户。检查以下示例代码:
使用以下代码创建一个 ClaimsController:
[Authorize]
public class ClaimsController : Controller
{
private UserManager<IdentityUser> userManager;
private SignInManager<IdentityUser> signInManager; //used to signin again and get the latest claims.
public ClaimsController(UserManager<IdentityUser> userMgr, SignInManager<IdentityUser> signMgr)
{
userManager = userMgr;
signInManager = signMgr;
}
public IActionResult Index()
{
return View(User?.Claims);
}
public IActionResult Create()
{
return View();
}
[HttpPost]
public async Task<IActionResult> CreateAsync(string claimType, string claimValue)
{
IdentityUser user = await userManager.GetUserAsync(HttpContext.User);
Claim claim = new Claim(claimType, claimValue, ClaimValueTypes.String);
IdentityResult result = await userManager.AddClaimAsync(user, claim);
HttpContext.User.Identities.FirstOrDefault().AddClaim(claim);
//signin again and get the latest claims.
await signInManager.SignInAsync(user, false, null);
if (result.Succeeded)
return RedirectToAction("Index");
else
Errors(result);
return View("Index", User.Claims);
}
[HttpPost]
public async Task<IActionResult> Delete(string claimValues)
{
IdentityUser user = await userManager.GetUserAsync(HttpContext.User);
string[] claimValuesArray = claimValues.Split(";");
string claimType = claimValuesArray[0], claimValue = claimValuesArray[1], claimIssuer = claimValuesArray[2];
Claim claim = User.Claims.Where(x => x.Type == claimType && x.Value == claimValue && x.Issuer == claimIssuer).FirstOrDefault();
IdentityResult result = await userManager.RemoveClaimAsync(user, claim);
await signInManager.SignInAsync(user, false, null);
if (result.Succeeded)
return RedirectToAction("Index");
else
Errors(result);
return View("Index", User.Claims);
}
void Errors(IdentityResult result)
{
foreach (IdentityError error in result.Errors)
ModelState.AddModelError("", error.Description);
}
}
索引页面中的代码(Index.cshtml):
@model IEnumerable<System.Security.Claims.Claim>
<h2 class="bg-primary m-1 p-1 text-white">Claims</h2>
<a asp-action="Create" class="btn btn-secondary">Create a Claim</a>
<table class="table table-sm table-bordered">
<tr>
<th>Subject</th>
<th>Issuer</th>
<th>Type</th>
<th>Value</th>
<th>Delete</th>
</tr>
@foreach (var claim in Model.OrderBy(x => x.Type))
{
<tr>
<td>@claim.Subject.Name</td>
<td>@claim.Issuer</td>
<td>@claim.Type</td>
<td>@claim.Value</td>
<td>
<form asp-action="Delete" method="post">
<input type="hidden" name="claimValues" value="@claim.Type;@claim.Value;@claim.Issuer" />
<button type="submit" class="btn btn-sm btn-danger">
Delete
</button>
</form>
</td>
</tr>
}
</table>
创建页面中的代码(Create.cshtml):
@model System.Security.Claims.Claim
@{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h1 class="bg-info text-white">Create Claim</h1>
<a asp-action="Index" class="btn btn-secondary">Back</a>
<div asp-validation-summary="All" class="text-danger"></div>
<form asp-action="Create" asp-controller="Claims" method="post">
<div class="form-group">
<label for="ClaimType">Claim Type:</label>
<input name="ClaimType" class="form-control" />
</div>
<div class="form-group">
<label for="ClaimValue">Claim Value:</label>
<input name="ClaimValue" class="form-control" />
</div>
<button type="submit" class="btn btn-primary">Create</button>
</form>
[注意] 使用上面的代码,在对用户添加或删除声明后,我们必须刷新当前用户,在这个示例中,我使用SignInManager.SignInAsync()方法重新登录并更新声明.
然后,截图如下:
编辑:
关于UserManager,它来源于Microsoft.AspNetCore.Identity和Microsoft.Extensions.Identity.Core.dll。
在 Asp.Net Core 3.1+ 版本应用程序中,配置身份和数据库后,在 Startup.ConfigureServices 中使用以下代码(这里您可能需要安装 EntityFrameWork 包,在我的示例中我安装了these packages):
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<IdentityUser, IdentityRole>(options => options.SignIn.RequireConfirmedAccount = true)
.AddDefaultUI()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddControllersWithViews().AddJsonOptions(opts =>
{
opts.JsonSerializerOptions.Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping;
});
services.AddRazorPages();
}
ApplicationDbContext 继承自 IdentityDbContext
public class ApplicationDbContext : IdentityDbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
[注意] 您可能需要使用Migration 来生成数据库。
之后,在控制器中,我们可以使用Dependency injection注册UserManager,代码如下:
public class ClaimsController : Controller
{
private readonly UserManager<IdentityUser> userManager;
private readonly SignInManager<IdentityUser> signInManager; //used to signin again and get the latest claims.
public ClaimsController(UserManager<IdentityUser> userMgr, SignInManager<IdentityUser> signMgr)
{
userManager = userMgr;
signInManager = signMgr;
}
更多详细信息,您可以查看以下文章:
Asp.net core Identity
Scaffold Identity in ASP.NET Core projects
最后,如果还是不能使用UserManager,作为一种变通方法,您可以通过dbcontext直接访问AspNetUserClaims表,然后使用EF核心管理用户的Claims。请参考以下代码:
[Authorize]
public class ClaimsController : Controller
{
private readonly UserManager<IdentityUser> userManager;
private readonly SignInManager<IdentityUser> signInManager; //used to signin again and get the latest claims.
private readonly ApplicationDbContext _dbcontext;
public ClaimsController(UserManager<IdentityUser> userMgr, SignInManager<IdentityUser> signMgr, ApplicationDbContext context)
{
userManager = userMgr;
signInManager = signMgr;
_dbcontext = context;
}
public IActionResult Index()
{
// access the UserClaims table and get the User's claims
var claims = _dbcontext.UserClaims.ToList();
//loop through the claims
//then based on the resut to creat claims
//Claim claim = new Claim(claimType, claimValue, ClaimValueTypes.String);
//and using the following code to add claim to current user.
HttpContext.User.Identities.FirstOrDefault().AddClaim(claim);
return View(HttpContext.User?.Claims);
}
要删除当前用户的声明,您可以尝试使用以下代码:
HttpContext.User.Identities.FirstOrDefault().RemoveClaim(claim);