微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

.NET Core 3.1中不会刷新Cookie

如何解决.NET Core 3.1中不会刷新Cookie

我有一个MVC .NET Core 3.1应用程序,该应用程序使用Open ID connect进行身份验证并将身份和令牌存储在cookie中。在应用程序执行某些API请求时,需要刷新令牌。我订阅ValidatePrincipal事件并在那里刷新令牌。该请求正常,但由于某些原因未更新cookie。

Startup.cs:

services.Configure<CookiePolicyOptions>(options =>
{
    options.CheckConsentNeeded = context => true;
    options.MinimumSameSitePolicy = SameSiteMode.None;
    options.OnAppendCookie = (e) =>
    {
        e.CookieOptions.Domain = <some domain>
    };
});
...
.AddCookie(options =>
{
    options.ExpireTimeSpan = TimeSpan.FromDays(30);
    options.Cookie.Domain = <some domain>;
    options.Cookie.IsEssential = true;
    options.Cookie.Name = <some name>
    options.EventsType = typeof(CookieAuthEvents);
})

CookieAuthEvents.cs(省略构造函数,成员声明和日志记录):

public override async Task ValidatePrincipal(CookieValidatePrincipalContext context)
{
    if (context.Principal.Identity.IsAuthenticated)
    {
        var Now = DateTime.UtcNow;
        var tokenExpiration = context.Properties.GetTokenExpiration();

        if (Now > tokenExpiration)
        {
            await UpdateCookies(context);
        }
    }
}

private async Task UpdateCookies(CookieValidatePrincipalContext context)
{
    var refreshToken = context.Properties.GetTokenValue(OpenIdConnectGrantTypes.RefreshToken);

    if (String.IsNullOrEmpty(refreshToken))
    {
        return;
    }

    var response = await GetTokenClient().RequestRefreshTokenAsync(refreshToken);

    if (!response.IsError)
    {
        WriteCookies(context,response);
    }
    else
    {
        context.RejectPrincipal();
    }
}

private void WriteCookies(CookieValidatePrincipalContext context,TokenResponse response)
{
    var tokens = new List<AuthenticationToken>
    {
        new AuthenticationToken
        {
            Name = OpenIdConnectParameterNames.IdToken,Value = response.IdentityToken
        },new AuthenticationToken
        {
            Name = OpenIdConnectParameterNames.Accesstoken,Value = response.Accesstoken
        },new AuthenticationToken
        {
            Name = OpenIdConnectParameterNames.RefreshToken,Value = response.RefreshToken
        },new AuthenticationToken
        {
            Name = OpenIdConnectParameterNames.TokenType,Value = response.TokenType
        }
    };

    var expiresAt = DateTime.UtcNow.AddSeconds(response.ExpiresIn);
    tokens.Add(new AuthenticationToken
    {
        Name = "expires_at",Value = expiresAt.ToString("o",CultureInfo.InvariantCulture)
    });

    var newPrincipal = GetNewPrincipal(context);

    context.ReplacePrincipal(newPrincipal);
    context.Properties.Storetokens(tokens);
    context.ShouldRenew = true;
}

private static ClaimsPrincipal GetNewPrincipal(CookieValidatePrincipalContext context)
{
    var claims = context.Principal.Claims.Select(c => new Claim(c.Type,c.Value)).ToList();
    var authTimeClaim = claims.FirstOrDefault(claim => claim.Type.Same("auth_time"));

    if (authTimeClaim != null)
    {
        claims.Remove(authTimeClaim);
    }

    claims.Add(new Claim("auth_time",DateTime.UtcNow.UnixTimestamp().ToString()));

    return new ClaimsPrincipal(new ClaimsIdentity(claims,context.Principal.Identity.AuthenticationType));
}

主要问题是,这在本地工作得很好。所有调用均正常,Cookie正确刷新。但是,当从开发机运行应用程序(我们将其托管在Azure App Service中)时,RequestRefreshTokenAsync调用成功,但是cookie并未更新,因此所有后续调用均使用旧令牌进行,导致400 invalid_grant错误。所以基本上我在日志中看到的是:

  • RequestRefreshTokenAsync成功。旧的refresh_token用于获取新的
  • ValidatePrincipal成功。这里的cookie应该被重写(包括一个新的refresh_token)
  • 一个请求-RequestRefreshTokenAsync失败。使用了旧版的refresh_token(即使它无效)。

我尝试使用cookie配置并将信号灯和锁放在ValidatePrincipal方法中,但是没有一个起作用。

有人知道会导致什么的原因吗?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。