摘要身份验证令牌在一段时间后无效

Posted

技术标签:

【中文标题】摘要身份验证令牌在一段时间后无效【英文标题】:Digest Authentication Token Invalid after some time 【发布时间】:2015-03-20 12:56:26 【问题描述】:

我正在开发我的第一个 Windows Phone 8.1 应用程序(如果这很重要,则通用,但目前只有 Windows Phone 实现)。起初一切都非常顺利,但是一旦我的应用程序运行了大约 25-30 分钟,我就不能再使用我的HttpClient。我使用Windows.Web.Http.HttpClient

在我第一次尝试s I used a singleHttpClientand reused it all the time. As I became aware that this is not working I started using a newHttpClient` 时为每个请求。但还是没有运气。

这是我获取新HttpClient的方法:

    private HttpClient GetClient()
    
        var filter = new HttpBaseProtocolFilter
        
            AllowUI = false,
            CacheControl =  WriteBehavior = HttpCacheWriteBehavior.NoCache ,
            ServerCredential =
                new PasswordCredential(
                BaseApiUri.ToString(),
                credentials.UserName,
                credentials.Password),
        ;

        var httpClient = new HttpClient(filter);
        var headers = httpClient.DefaultRequestHeaders;
        var httpConnectionOptionHeaderValueCollection = headers.Connection;
        httpConnectionOptionHeaderValueCollection.Clear();
        headers.Accept.TryParseAdd("application/json");
        headers.CacheControl.TryParseAdd("no-cache");
        headers.Add("Pragma", "no-cache");
        headers.Add("Keep-Alive", "false");
        headers.Cookie.Clear();

        return httpClient;
    

设置标头和清除 cookie 的额外代码是我试图阻止可能发生的某种连接缓存的尝试。但还是没有运气。

我的 API 请求方法如下:

    private async Task<bool> PostNoResponseRequestTo(string relativeUri, object requestContent, CancellationToken cancellationToken)
    
        var targetUri = new Uri(BaseApiUri, relativeUri);
        var requestJson = JsonConvert.SerializeObject(requestContent);
        var content = new HttpStringContent(requestJson, UnicodeEncoding.Utf8, "application/json");
        try
        
            using (var httpClient = this.GetClient())
            
                var post =
                    await httpClient.PostAsync(targetUri, content).AsTask(cancellationToken).ContinueWith(
                        async request =>
                            
                                using (var response = await request)
                                
                                    return response.IsSuccessStatusCode;
                                
                            ,
                        cancellationToken);

                return await post;
            
        
        catch (Exception)
        
            return false;
        
    

这可以正常工作大约 25-30 分钟,之后对 api 的调用突然开始失败。我开始收到401,但正如您所见,我已经指定了凭据,并且因为这些凭据正在工作并且不会更改(硬编码它们以对此进行测试),我开始相信问题出在 API 方面。

这是我得到的回复:

StatusCode: 401, ReasonPhrase: 'Unauthorized', Version: 2, Content:      Windows.Web.Http.HttpStreamContent, Headers:

    Server: Microsoft-IIS/8.5
    Date: Fri, 20 Mar 2015 14:25:06 GMT
    WWW-Authenticate: Digest qop="auth",algorithm=MD5-sess,nonce="+Upgraded+NounceRemoved",charset=utf-8,realm="Digest", Negotiate, NTLM
    X-Powered-By: ASP.NET


    Content-Length: 1344
    Content-Type: text/html

我的 API 由一个带有 ServiceStack 的 Asp.Net 项目组成,以实现其 API 功能。 这是在具有激活摘要身份验证的 IIS 上运行的(所有其他都被禁用)。

通过检查日志,我发现每次成功调用之前都有一个失败的 API 调用。但是,如果我是对的,这是摘要式身份验证的设计,因为我还没有找到一种方法来告诉客户端对方正在使用摘要式身份验证。我能够在我的其他 .Net 项目中指定此类信息,但由于某种原因,Microsoft 更改了 HttpClient 的代码(和命名空间)。我也知道原始命名空间中的HttpClient 可以通过 nuget 获得,但这对我不起作用,因为我一拨打任何电话就会在输出窗口中收到错误消息。这会在没有任何信息的情况下关闭我的应用程序。

回到日志,我能够在扩展日志记录和分析它们的工具的帮助下获得一些信息。错误类似于(现在无法访问它,稍后将对其进行编辑):'Invalid token passing to function/method'.

我真的希望有人可以帮助我解决这个问题,因为它使应用程序几乎无法使用。我的用户必须每 15 分钟重新启动一次应用才能进入保存站点。

感谢所有对我有帮助的建议。

【问题讨论】:

您设法解决了这个问题吗?我现在有同样的问题(在 UWP 中)。整整 10 分钟后,我只得到 401 作为响应... @Dust258 不,抱歉,我们使用的是工作区。我们只是多次尝试身份验证,这对我们有用。 【参考方案1】:

尝试检查 IIS 中的机器密钥设置。如果每次重新启动应用程序池时tick都会生成一个新密钥,则在运行时自动生成。这可能会导致您的问题。机器密钥可以在服务器、网站或应用程序级别设置。由于激活的摘要身份验证已加密,这可能是问题所在。

Managing Websites with IIS Manager (part 6) - The Machine Key and Windows Authentication

【讨论】:

从来不知道这个设置,只是试了一下。这无济于事,但我觉得它增加了大约 5 分钟的时间。但这可能只是我。还用更多信息编辑了我的问题。

以上是关于摘要身份验证令牌在一段时间后无效的主要内容,如果未能解决你的问题,请参考以下文章

摘要身份验证生成“令牌”

Laravel JWT 令牌在身份验证 JWT 方法中刷新后无效

存储用于离线身份验证的令牌

1 小时后身份验证令牌无效 - Firebase 中的磁盘持久性

Firebase 身份验证 iOS 12 无效令牌

Symfony:身份验证请求失败:无效的 CSRF 令牌