SendAsync在Web API返回空

本文关键字:返回 API Web SendAsync | 更新日期: 2023-09-27 18:06:42

当用户在授权令牌过期或令牌无效时试图调用服务时,我试图返回一个适当的错误消息。

我遇到的问题是它第一次被调用,消息被正确发送,但在第一次调用SendAsync方法4次之后,消息数据返回null。

我很困惑为什么它循环4次,我试着通过它,但我不能得到任何进一步的代码。

代码如下:

protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
                                                           CancellationToken cancellationToken)
    {
        if (request.Headers != null)
        {
             // ....
             if (request.Headers.GetValues(CustomTokenHeader).FirstOrDefault() == null)
             {
                  //unauthorized response(401)
                  return FromResult(_unauthorizedResponse);
             }
             var authHeader = request.Headers.GetValues(CustomTokenHeader).FirstOrDefault();
             if (String.IsNullOrWhiteSpace(authHeader))
             {
                 //unauthorized response(401)
                 return FromResult(_unauthorizedResponse);
             }
             //authenticate token
             return HandleTokenAuthentication(request, cancellationToken, authHeader);
        }
    }
    static Task<T> FromResult<T>(T t)
    {
        var tcs = new TaskCompletionSource<T>();
        tcs.SetResult(t);
        return tcs.Task;
    }

    private Task<HttpResponseMessage> HandleTokenAuthentication(HttpRequestMessage request, CancellationToken cancellationToken, string authHeader)
    {
        //parse token
        var token = ParseToken(authHeader);
        if (String.IsNullOrWhiteSpace(token))
        {
            //unauthorized response(401)
            return FromResult(_unauthorizedResponse);
        }
        //decrypt token
        var tokenInfo = DecryptToken(token);
        if (tokenInfo == null)
        {
            //unauthorized response(401)
            return FromResult(_unauthorizedResponse);
        }
        //validate token
        var claims = ValidateToken(tokenInfo, token);
        if (claims == null)
        {
            //unauthorized response(401)
            return FromResult(_unauthorizedTokenExpired);
        }
        var principal = CheckCustomAuthorization(claims);
         if (principal == null)
        {
            //unauthorized response(401)
            return FromResult(_unauthorizedResponse);
        }
        if (!principal.Identity.IsAuthenticated)
        {
            var loginFailureMessage = new HttpResponseMessage(HttpStatusCode.Unauthorized)
            {
                Content = new StringContent(((AgencyClaims)principal.Identity).LoginFailureReason)
            };
            return FromResult(loginFailureMessage);
        }
        //assign principal
        Thread.CurrentPrincipal = principal;
        return base.SendAsync(request, cancellationToken)
                               .ContinueWith(task => AuthorizedResponse(request, task.Result));
    }
    static HttpResponseMessage AuthorizedResponse(HttpRequestMessage request, HttpResponseMessage response)
    {
        if ((request.Method == HttpMethod.Get && response.StatusCode == HttpStatusCode.OK
            && !response.Headers.Contains(CustomTokenHeader))
            || (request.Method == HttpMethod.Post && response.StatusCode == HttpStatusCode.Created
            && !response.Headers.Contains(CustomTokenHeader)))
        {
            var token = ((AgencyClaims) Thread.CurrentPrincipal.Identity).Token;
            response.Headers.Add(CustomTokenHeader, Convert.ToBase64String(Encoding.ASCII.GetBytes(token)));
        }
        return response;
    }
readonly HttpResponseMessage _unauthorizedResponse =
        new HttpResponseMessage(HttpStatusCode.Unauthorized) { Content = new StringContent("PROPER ERROR MESSAGE")};

成功的响应:

 <data contentType="text/plain; charset=utf-8" contentLength="21"><![CDATA[Authentication failed]]></data>

下面是第一个成功响应后的响应:

<data contentType="null" contentLength="0"><![CDATA[]]></data>

下面是请求的一部分:

GET http://localhost:20559/api/Service?Name=Jack HTTP/1.1

SendAsync在Web API返回空

好的,我能够解决这个问题。_unauthorizedResponse类变量以某种方式允许代码成功运行一次,但不允许第二次运行。这个问题与readonly修饰符无关,因为没有它仍然无法工作。我不确定这是如何工作的(也许有人在这里可以解释),但是通过将它们移动到方法内的局部作用域,它每次都能够正确运行。