将自定义数据存储在Identity Cookie中 [英] Store custom datas in Identity Cookie

查看:81
本文介绍了将自定义数据存储在Identity Cookie中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以在Identity API生成的Cookie中存储来自用户的一些自定义数据?

Is there a way to store some custom datas from the user inside the cookie generated by the Identity API ?

我们正在构建一个多租户应用程序,因此多个公司可以访问我们应用程序的同一实例.这就是为什么对于特定用户,我需要在关闭浏览器后返回到Web应用程序时,将用户的公司代码存储在身份cookie中,以便从用户那里检索数据.

We are building an multi-tenant application, and so multiple companies can access to the same instance of our application. That's why I need, for a specific user, to store company code from the user in the identity cookie to retrieve the datas from the user when he returned on the web application after closing the browser.

推荐答案

您可以通过实现自定义UserClaimsPrincipalFactory并为您的商店编号添加自定义声明来实现这一点,然后将其与其他声明一起存储在cookie中.

you could achieve that by implementing a custom UserClaimsPrincipalFactory and adding a custom claim for your store number, then it would be stored in the cookie with the other claims.

下面是我的项目中的示例代码,我在其中添加了几个自定义声明,包括SiteGuid,因为我的场景也是多租户

Below is example code from my project where I am adding several custom claims including a SiteGuid because my scenario is also multi-tenant

using cloudscribe.Core.Models;
using Microsoft.AspNet.Identity;
using Microsoft.Extensions.OptionsModel;
using System;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;

namespace cloudscribe.Core.Identity
{
    public class SiteUserClaimsPrincipalFactory<TUser, TRole> : UserClaimsPrincipalFactory<TUser, TRole>
    where TUser : SiteUser
    where TRole : SiteRole
{
    public SiteUserClaimsPrincipalFactory(
        ISiteRepository siteRepository,
        SiteUserManager<TUser> userManager,
        SiteRoleManager<TRole> roleManager, 
        IOptions<IdentityOptions> optionsAccessor) : base(userManager, roleManager, optionsAccessor)
    {
        if (siteRepository == null) { throw new ArgumentNullException(nameof(siteRepository)); }

        siteRepo = siteRepository;
        options = optionsAccessor.Value;
    }

    private ISiteRepository siteRepo;
    private IdentityOptions options;

    public override async Task<ClaimsPrincipal> CreateAsync(TUser user)
    {
        if (user == null)
        {
            throw new ArgumentNullException("user");
        }

        var userId = await UserManager.GetUserIdAsync(user);
        var userName = await UserManager.GetUserNameAsync(user);

        var id = new ClaimsIdentity(
            options.Cookies.ApplicationCookie.AuthenticationScheme,
            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)));
            }

            if (UserManager.SupportsUserRole)
            {
                var roles = await UserManager.GetRolesAsync(user);
                foreach (var roleName in roles)
                {
                    id.AddClaim(new Claim(Options.ClaimsIdentity.RoleClaimType, roleName));
                    if (RoleManager.SupportsRoleClaims)
                    {
                        var role = await RoleManager.FindByNameAsync(roleName);
                        if (role != null)
                        {
                            id.AddClaims(await RoleManager.GetClaimsAsync(role));
                        }
                    }
                }
            }
            if (UserManager.SupportsUserClaim)
            {
                id.AddClaims(await UserManager.GetClaimsAsync(user));
            }

            ClaimsPrincipal principal = new ClaimsPrincipal(id);

            if (principal.Identity is ClaimsIdentity)
            {
                ClaimsIdentity identity = (ClaimsIdentity)principal.Identity;

                Claim displayNameClaim = new Claim("DisplayName", user.DisplayName);
                if (!identity.HasClaim(displayNameClaim.Type, displayNameClaim.Value))
                {
                    identity.AddClaim(displayNameClaim);
                }

                Claim emailClaim = new Claim(ClaimTypes.Email, user.Email);
                if (!identity.HasClaim(emailClaim.Type, emailClaim.Value))
                {
                    identity.AddClaim(emailClaim);
                }

                ISiteSettings site = await siteRepo.Fetch(user.SiteId, CancellationToken.None);

                if (site != null)
                {
                    Claim siteGuidClaim = new Claim("SiteGuid", site.SiteGuid.ToString());
                    if (!identity.HasClaim(siteGuidClaim.Type, siteGuidClaim.Value))
                    {
                        identity.AddClaim(siteGuidClaim);
                    }

                }      

            }

            return principal;

        }
    }
}

然后在启动"中,您需要注册自定义工厂,以便它被注入并使用,而不是默认工厂

Then in Startup you need to register your custom factory so it gets injected and used instead of the default one

services.AddScoped<IUserClaimsPrincipalFactory<SiteUser>, SiteUserClaimsPrincipalFactory<SiteUser, SiteRole>>();

另一种方法是使用Claims Transformation,但是这种方法不将多余的声明存储在Cookie中,而是更新每个请求的声明,也就是说,在请求的生命周期内,它将向cookie中的声明添加更多声明但不会修改Cookie中的声明.

another approach is to use Claims Transformation, however this approach does not store the extra claims in a cookie but instead updates the claims on each request, that is it adds more claims to the ones from the cookie for the lifetime of the request but doesn't modify the claims in the cookie.

public class ClaimsTransformer : IClaimsTransformer
{
    public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
    {
        ((ClaimsIdentity)principal.Identity).AddClaim(new Claim("ProjectReader", "true"));
        return Task.FromResult(principal);
    }
}

然后在startup.cs中:

then in startup.cs:

app.UseClaimsTransformation(new ClaimsTransformationOptions
{
    Transformer = new ClaimsTransformer()
});

这篇关于将自定义数据存储在Identity Cookie中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆