使用 ASP.NET Identity 是否可以在现有会话期间动态添加和删除声明?

cra*_*cra 5 c# asp.net asp.net-mvc asp.net-identity

我尝试在 Asp.Net 4.5.2 中使用 Identity 2 成功登录后动态添加和删除声明(在本例中为角色)。我的应用程序有一个身份验证数据库,其中包含 AspNetUsers、AspNetRoles 和 AspNetUserRoles 表等以及许多其他数据库。在用户会话过程中,我的用户可以在其他数据库之间切换,并且他们当前的声明(角色)会根据他们当前使用的数据库进行修改。因此,我想在整个会话期间添加和删除声明。这允许我根据用户当前的授权修改用户有权访问的视图。

我已经在堆栈溢出和 MS Identity 帮助页面(例如它们)中对此进行了很多天的研究,但找不到与我尝试做的任何类似的内容。根据我所了解到的情况,我已经能够添加自己的新声明,但只能在登录过程中添加,在任何其他点更改它们都适用于该请求,但更改不会持续存在,并且在下一个请求时会丢失进来。

据我所知,当在登录期间添加声明时,它们会在会话 cookie 中进行编码,而当我在任何其他点添加它们时,cookie 不会被修改。根据我目前的理解,这发生在 OWIN 管道的 Identity 模块中。我成功添加声明的方法是ApplicationUser 中的GenerateUserIdentityAsync 方法(派生自IdentityUser.

    public class ApplicationUser : IdentityUser
    {
        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);

            // Add custom user claims here
            userIdentity.AddClaim(new Claim("Customer_ID", Convert.ToString(this.Customer_ID)));
            userIdentity.AddClaim(new Claim("LastName", this.LastName));
            userIdentity.AddClaim(new Claim("FirstName", this.FirstName));

            userIdentity.AddClaim(new Claim(ClaimTypes.Role, "TestRole", null, null, "TestIssuer"));

            return userIdentity;
        }
Run Code Online (Sandbox Code Playgroud)

不幸的是,这对我的情况没有帮助,因为我正在尝试在 OWIN 管道之外添加/删除声明。

我正在尝试做的事情到底是可能的还是我的做法完全错误?我本以为动态修改授权并不罕见。

我研究过的许多堆栈溢出问题包括: 如何在 ASP.NET Identity 中添加声明ASP.NET Identity EF 中的动态用户声明以及 ASP.NET Identity and Claims。它们都没有完全涵盖我正在尝试做的事情。

Pay*_*ali 0

在 ASP.net 中:

\n

向现有身份添加声明似乎是一项小任务。但是,事情并没有那么容易。我们可以构建一个中间件类并尝试如下所示的内容。

\n
foreach(var role in user.Roles)\n {\n    var claim = new Claim(newIdentity.RoleClaimType, role.Name);\n    identity.AddClaim(claim);\n  }\n
Run Code Online (Sandbox Code Playgroud)\n

在 Asp.net core 中:

\n

这是编辑现有身份的正确方法,它称为声明转换。基本上,我们必须编写一个实现 IClaimsTransformation 接口的自定义类。文档没有提供有关它的太多信息,但最重要的是 \xe2\x80\x93 我们需要克隆给定的身份。

\n

简而言之,\xe2\x80\x99 是该过程的进行方式:

\n
    \n
  1. 克隆当前用户身份

    \n
  2. \n
  3. 添加自定义声明

    \n
  4. \n
  5. 返回克隆身份

    \n
    public class AddRolesClaimsTransformation : IClaimsTransformation\n{\n    private readonly IUserService _userService; public class AddRolesClaimsTransformation : IClaimsTransformation\n    {\n        private readonly IUserService _userService;\n\n        public AddRolesClaimsTransformation(IUserService userService)\n{\n\n    _userService = userService;\n}\n\npublic async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)\n{\n    // Clone current identity\n    var clone = principal.Clone();\n    var newIdentity = (ClaimsIdentity)clone.Identity;\n\n    // Support AD and local accounts\n    var nameId = principal.Claims.FirstOrDefault(c => c.Type ==\n        ClaimTypes.NameIdentifier || c.Type == ClaimTypes.Name);\n    if (nameId == null)\n    {\n        return principal;\n    }\n\n    // Get user from database\n    var user = await _userService.GetByUserName(nameId.Value);\n    if (user == null)\n    {\n        return principal;\n    }\n\n    // Add role claims to cloned identity\n    foreach (var role in user.Roles)\n    {\n        var claim = new Claim(newIdentity.RoleClaimType, role.Name);\n        newIdentity.AddClaim(claim);\n    }\n\n    return clone;\n} }\n
    Run Code Online (Sandbox Code Playgroud)\n
  6. \n
\n

最后要做的事情是在 Startup 类的 ConfigureServices() 方法中通过依赖注入注册声明转换。

\n
services.AddScoped<IClaimsTransformation, AddRolesClaimsTransformation>();\nenter code here\n
Run Code Online (Sandbox Code Playgroud)\n

基于https://gunnarpeipman.com/aspnet-core-adding-claims-to-existing-identity/

\n