【问题标题】:Update a claim in an ASP.NET Core 2.1 Authentication Cookie更新 ASP.NET Core 2.1 身份验证 Cookie 中的声明
【发布时间】:2018-12-29 12:12:10
【问题描述】:

如何更新 ASP.NET Core 2.1 身份验证 Cookie 中的声明值?

我的问题的一点背景:

我有一个使用 Cookie 身份验证的 dotnet Core 2.1 MVC 项目。

网站从使用不记名令牌进行身份验证的 API 获取大部分数据。不记名令牌的寿命相当短,API 还返回一个刷新令牌以获取新的不记名令牌。

当用户登录时,我从 API 获取令牌并将其作为声明存储在 auth cookie 中,如下所示:

var props = new AuthenticationProperties{  ...  };

var claims = new[]
{
    new Claim("ApiAccessToken", apiToken.AccessToken),
    new Claim("ApiRefreshToken", apiToken.RefreshToken),
    // other claims ...
};

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

await Request.HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme,
    new ClaimsPrincipal(identity), props);

我在调用 API 之前使用 Polly 确保身份验证,如果第一次尝试 API 得到 401,我使用刷新令牌来获取新的不记名令牌。我想用这些新值更新 auth cookie 中的 ApiAccessToken 和 ApiRefreshToken 声明。


或者有没有更好的方法来处理这种情况?

谢谢。

【问题讨论】:

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


    【解决方案1】:

    我相信我的问题的答案是“你不知道”。

    我最终创建了另一个包含不记名令牌和刷新令牌的 cookie。我加密了刷新令牌以防万一。

    示例扩展方法代码:

    public static void AppendApiAuthCookie(this HttpContext context, ApiAuthToken token, Guid userId)
    {
        context.Response.Cookies.Append("mytoken", $"bearerToken:{token.BearerToken}|refreshtoken:{token.RefreshToken}|uid:{userId}", 
         new CookieOptions
         {
            HttpOnly = true,
            SameSite = SameSiteMode.Strict,
            Expires = DateTimeOffset.UtcNow.AddHours(24),
         });
    }
    

    然后我在退出时删除 cookie。

    注意(这可能是显而易见的):在我的场景中,使用 Polly 来确保身份验证,Polly 策略处理程序会从身份验证提供程序获取新令牌并更新 cookie。您刚刚存储在 cookie 中的新值在当前请求上下文中的 cookie 中不可用。因此,您需要确保在请求的生命周期内将新的不记名令牌保存在某个地方,以便您可以在当前请求上下文中获取它。

    【讨论】:

    • 我无法使用此方法附加 cookie,因为我在 HttpContext.Request.Cookies.Append 方法中只有 keyvaluepair 参数
    【解决方案2】:

    您可以像代码一样将令牌存储在 cookie 中。那么你可以像这样得到令牌:

    var apiAccessToken = User.Identities.FirstOrDefault(i => i.AuthenticationType == "Cookies")?.Claims.FirstOrDefault(c => c.Type == "ApiAccessToken")?.Value;
    
    var apiRefreshToken = User.Identities.FirstOrDefault(i => i.AuthenticationType == "Cookies")?.Claims.FirstOrDefault(c => c.Type == "ApiRefreshToken")?.Value;
    

    最后,您可以像这样使用 HttpClient 获取或发布数据到 API:

    public async Task<T> GetWithTokenAsync<T>(HttpClient httpClient, string uri, string token)
    {
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
        var response = await httpClient.GetAsync(uri);
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadAsAsync<T>();
    }
    

    “T”是你获取或发布的数据类型。

    在“Startup.cs”的“ConfigureServices”中你应该像这样配置:

    services.AddHttpClient("YourApiName", client =>
    {
        client.BaseAddress = new Uri("The base address of your api");
        client.DefaultRequestHeaders.Add("Accept", "application/json");
        client.DefaultRequestHeaders.Add("User-Agent", "The application name of your client");
        client.DefaultRequestHeaders.Add("ApplicationId", "The application id of your client");
    });
    

    【讨论】:

      猜你喜欢
      • 2018-12-30
      • 1970-01-01
      • 2020-10-09
      • 2017-03-30
      • 1970-01-01
      • 1970-01-01
      • 2018-09-02
      • 2017-06-17
      • 2018-02-24
      相关资源
      最近更新 更多