簡體   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