【问题标题】:Identity 3 - store claims in database but not cookie身份 3 - 将声明存储在数据库中,但不存储 cookie
【发布时间】:2017-05-24 14:51:58
【问题描述】:

In.net core Identity 3 - 默认情况下是否可以不在 Identity cookie 中存储用户声明或角色声明,而只将它们存储在数据库中?

换句话说,如果您想访问声明,则必须显式加载它们。

无法弄清楚如何使用 Identity 的内置功能和默认架构进行配置。

【问题讨论】:

  • 但是为什么呢? Cookie 是加密的,除了您之外没有人可以访问它。
  • 问题不在于它是否加密或它有多安全。问题是 cookie 变得太大了。我有很多角色声明,并且它变得太大而无法在 Http 标头中发送。
  • 啊,那是公平的。我可以看到的一种解决方法是不要将所有数据放入声明中,而是将这些信息分开并通过user.Id 进行查询 - 无论如何您都将查询数据库,在哪里查询以获取数据是否重要:索赔表还是您自己的结构?
  • 这是一个很好的观点,我也在考虑这一点——我可能不得不走这条路。由于 Identity 为您提供了开箱即用的 AspNetRoleClaims 表,只是试图让它与它一起工作 - 我想我也许可以有选择地控制哪些声明进入 cookie 以控制大小。

标签: asp.net-core asp.net-identity


【解决方案1】:

通过覆盖 UserClaimsPrincipalFactory 类,我仍然能够使用内置的 AspNetRoleClaims 表,但不将这些表包含在 cookie 中。再次,原因是我有许多角色声明,并且 cookie 变得太大。

我创建了自己的类 AppClaimsPrincipalFactory,它继承自 UserClaimsPrincipalFactory 并覆盖了 CreateAsync 方法:

public class AppClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser, IdentityRole>
{
    public AppClaimsPrincipalFactory(UserManager<ApplicationUser> userManager, RoleManager<IdentityRole> roleManager, IOptions<IdentityOptions> optionsAccessor) : base(userManager, roleManager, optionsAccessor)
    {
    }
    public override async Task<ClaimsPrincipal> CreateAsync(ApplicationUser user)
    {
        if (user == null)
        {
            throw new ArgumentNullException(nameof(user));
        }
        var userId = await UserManager.GetUserIdAsync(user);
        var userName = await UserManager.GetUserNameAsync(user);
        var id = new ClaimsIdentity(Options.Cookies.ApplicationCookieAuthenticationScheme,
            Options.ClaimsIdentity.UserNameClaimType,
            Options.ClaimsIdentity.RoleClaimType);
        id.AddClaim(new Claim(Options.ClaimsIdentity.UserIdClaimType, userId));
        id.AddClaim(new Claim(Options.ClaimsIdentity.UserNameClaimType, userName));
        if (UserManager.SupportsUserSecurityStamp)
        {
            id.AddClaim(new Claim(Options.ClaimsIdentity.SecurityStampClaimType,
                await UserManager.GetSecurityStampAsync(user)));
        }

        // code removed that adds the role claims 

        if (UserManager.SupportsUserClaim)
        {
            id.AddClaims(await UserManager.GetClaimsAsync(user));
        }
        return new ClaimsPrincipal(id);
    }
}

在 Startup.cs ConfigureServices 中,然后我将其注册到容器中,如下所示:

services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

        // override UserClaimsPrincipalFactory (to remove role claims from cookie )
        services.AddScoped<IUserClaimsPrincipalFactory<ApplicationUser>, AppClaimsPrincipalFactory>();

【讨论】:

【解决方案2】:

另一种选择是不在 UserStore 实现上实现 IUserClaimStore 接口。作为 EF 包的一部分提供的默认实现确实实现了此接口,因此声明会自动存储和检索。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-26
    • 1970-01-01
    • 1970-01-01
    • 2019-05-14
    • 2013-02-20
    • 1970-01-01
    • 2020-10-22
    • 1970-01-01
    相关资源
    最近更新 更多