繁体   English   中英

如何在 Asp.Net Core 3.1 中为现有 HttpContext 用户保留新添加的声明

[英]How to persist newly added claims to existing HttpContext user in Asp.Net Core 3.1

我是 .Net Core 的新手,并在Startup.cs文件中按如下方式配置了身份验证 -

public void ConfigureServices(IServiceCollection services)
    {
        // To be able to access HttpContext
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();            

        services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(o => o.LoginPath = "/login");

        // Most of the code removed for brevity            
    }

用户登录后,我们通过 -

public static async Task AuthenticateUserAsync(HttpContext httpContext, AuthorizedUser authorizedUser)
    {
        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.NameIdentifier, authorizedUser.UserUid.ToString()),
            new Claim(CustomClaimTypes.CompanyGuid, authorizedUser.CompanyUid.ToString())
        };

        var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);

        var authProperties = new AuthenticationProperties
        {
            // Refreshing the authentication session should be allowed.
            //AllowRefresh = <bool>,

            // The time at which the authentication ticket was issued.
            IssuedUtc = DateTimeOffset.UtcNow,

            // The time at which the authentication ticket expires. A 
            // value set here overrides the ExpireTimeSpan option of 
            // CookieAuthenticationOptions set with AddCookie.
            ExpiresUtc = DateTimeOffset.UtcNow.AddHours(1),

            // Whether the authentication session is persisted across 
            // multiple requests. When used with cookies, controls
            // whether the cookie's lifetime is absolute (matching the
            // lifetime of the authentication ticket) or session-based.
            IsPersistent = false,

            //RedirectUri = <string>
            // The full path or absolute URI to be used as an http 
            // redirect response value.
        };

        await httpContext.SignInAsync(
            CookieAuthenticationDefaults.AuthenticationScheme,
            new ClaimsPrincipal(claimsIdentity),
            authProperties);
    }

在某些服务类中,我们检索门户信息并尝试将其保存在声明中,如下所示 -

public async Task AddPortalToCurrentUserClaimsAsync(Guid companyUid, Guid userUid)
    {
        var portal = await _unitOfWork.Portals.All().FirstOrDefaultAsync(p => p.CompanyUid == companyUid && p.UserUid == userUid).ConfigureAwait(false);
        if (portal == null) return;

        var claims = new List<Claim>
        {
            new Claim(CustomClaimTypes.PortalId, portal.Id.ToString()),
            new Claim(CustomClaimTypes.PortalName, portal.Name)
        };

        var claimsIdentity = new ClaimsIdentity(claims);
        _httpContextAccessor.HttpContext.User.AddIdentity(claimsIdentity);
    }

当我尝试在进一步的请求中检索此声明时,我得到了空值。

var portalId = _httpContextAccessor.HttpContext.User.FindFirst(CustomClaimTypes.PortalId);
var portalName = _httpContextAccessor.HttpContext.User.FindFirst(CustomClaimTypes.PortalName);

我怎样才能让这些新添加的声明坚持进一步的请求?

我从分享的文章中读到

要创建保存用户信息的 cookie,请构造ClaimsPrincipal 用户信息被序列化并存储在cookie中。 SignInAsync创建一个加密的 cookie 并将其添加到当前响应中。 如果未指定AuthenticationScheme ,则使用默认方案。

因此,您不能向已创建的ClaimsPrincipal添加声明,因为声明已存储在 cookie 中。

对我ClaimsPrincipal解决方案是创建新的ClaimsPrincipal并创建新的 cookie 作为 -

public async Task AddPortalToCurrentUserClaimsAsync(Guid companyUid, Guid userUid)
        {
            var portal = await _unitOfWork.Portals.All().FirstOrDefaultAsync(p => p.CompanyUid == companyUid && p.UserUid == userUid).ConfigureAwait(false);
            if (portal == null) return;

            var claims = new List<Claim>
            {
                new Claim(ClaimTypes.NameIdentifier, userUid.ToString()),
                new Claim(CustomClaimTypes.CompanyGuid, companyUid.ToString()),
                new Claim(CustomClaimTypes.PortalId, portal.Id.ToString()),
                new Claim(CustomClaimTypes.PortalName, portal.Name)
            };

            var authProperties = new AuthenticationProperties
            {
                IssuedUtc = DateTimeOffset.UtcNow,
                ExpiresUtc = DateTimeOffset.UtcNow.AddHours(1),
                IsPersistent = false
            };

            const string authenticationType = "Cookies";
            var claimsIdentity = new ClaimsIdentity(claims, authenticationType);
            await _httpContextAccessor.HttpContext.SignInAsync(authenticationType, new ClaimsPrincipal(claimsIdentity), authProperties);
        }

声明中只添加上在ClaimsPrinciple /用户如果坚持SignInAsync再次被调用。 因此,将找到您的第一个声明,因为它是在用户登录之前添加的。但是,随着您添加更多声明,它们不会被“保存”,因为用户的身份尚未重置。

如果您要添加更多声明,在初始登录之前,这应该有效:

var authProperties = new AuthenticationProperties
{
    IssuedUtc = DateTimeOffset.UtcNow,
    ExpiresUtc = DateTimeOffset.UtcNow.AddHours(1),
    IsPersistent = false,
};

await httpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme,
    _httpContextAccessor.HttpContext.User,
    authProperties);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM