客户端Blazor身份验证令牌在服务器端已过期

时间:2020-02-25 11:57:43

标签: webassembly blazor-client-side

我在使用blazor身份验证的客户端令牌时遇到问题。我基于此博客文章实施了身份验证,我正在使用Webassembly项目。

https://chrissainty.com/securing-your-blazor-apps-introduction-to-authentication-with-blazor/

https://chrissainty.com/securing-your-blazor-apps-authentication-with-clientside-blazor-using-webapi-aspnet-core-identity/

https://chrissainty.com/securing-your-blazor-apps-configuring-role-based-authorization-with-client-side-blazor/

几乎所有功能都正常,但是我遇到了问题。在服务器端,身份验证令牌已过期,但是在客户端,我在本地存储上仍具有身份验证令牌。我获取本地状态的功能:

   public override async Task<AuthenticationState> GetAuthenticationStateAsync()
    {
        var savedToken = await _localStorage.GetItemAsync<string>("authToken");            

        if (string.IsNullOrWhiteSpace(savedToken))
        {
            return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
        }

        _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", savedToken);

        return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity(ParseClaimsFromJwt(savedToken), "jwt")));
    }

好吧,查看响应头,我可以看到服务器告诉我我的本地令牌已过期,但是我不知道如何在客户端获取此信息。因此,我的客户端告诉我,我已通过身份验证,但在服务器端,我不是。我不想每次我的方法GetAuthenticationStateAsync运行以手动清除本地存储令牌时都要求对此进行测试。如何应对这种行为的最佳方法是什么?我的代码缺少东西了吗?

标头响应:“ www-authenticate:Bearer error =” invalid_token“,error_description =”令牌在'02 / 24/2020 11:52:35'“”

过期

谢谢。

2 个答案:

答案 0 :(得分:1)

我也跟踪了与您相同的博客文章,看来我们必须在客户端进行自己的到期检查。在客户端的ApiAuthenticationStateProvider中,我这样做了:

public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
    var savedToken = await _localStorage.GetItemAsync<string>("authToken");
    var anonymousState = new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));

    // Not authenticated
    if (string.IsNullOrWhiteSpace(savedToken))
    {
        return anonymousState;
    }

    var claims = ParseClaimsFromJwt(savedToken);
    // Checks the exp field of the token
    var expiry = claims.Where(claim => claim.Type.Equals("exp")).FirstOrDefault();
    if (expiry == null)
        return anonymousState;

    // The exp field is in Unix time
    var datetime = DateTimeOffset.FromUnixTimeSeconds(long.Parse(expiry.Value));
    if (datetime.UtcDateTime <= DateTime.Now)
        return anonymousState;

    _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", savedToken);

    return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity(claims, "jwt")));
}

虽然不漂亮,但现在可以完成工作。

答案 1 :(得分:1)

Richard Holmes的解决方案稍作修改即可为我工作:处于比较状态 (datetime.UtcDateTime <= DateTime.Now)DateTime.Now需要更改为DateTime.UtcNow