【问题标题】:Client side Blazor authentication token expired on server side客户端 Blazor 身份验证令牌在服务器端过期
【发布时间】:2020-06-09 03:46:04
【问题描述】:

我在使用 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="The token expired at '02/24/2020 11:52:35'"”

谢谢。

【问题讨论】:

  • 也遇到了同样的问题,你找到解决办法了吗?

标签: webassembly blazor-client-side


【解决方案1】:

Richard Holmes 的解决方案对我来说很好,只需稍作修改:比较 (datetime.UtcDateTime

【讨论】:

    【解决方案2】:

    我关注了您所做的相同博客文章,看来我们必须在客户端进行自己的过期检查。在客户端的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.UtcNow)
            return anonymousState;
    
        _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", savedToken);
    
        return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity(claims, "jwt")));
    }
    

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

    【讨论】:

    • 谢谢,这正是我所需要的,现在想想很明显,因为所有的评估都是在客户端上进行的
    • 重要!看看 He-Wolf 的答案,与 DateTime.UtcNow 相比,而不是 DateTime.Now 是至关重要的
    猜你喜欢
    • 1970-01-01
    • 2012-08-28
    • 2011-11-04
    • 1970-01-01
    • 1970-01-01
    • 2012-04-15
    • 2019-12-01
    • 2022-08-16
    • 1970-01-01
    相关资源
    最近更新 更多