当用户尝试在授权令牌过期时调用服务或者他们的令牌无效时,我正在尝试返回相应的错误消息。
我遇到的问题是第一次调用它时,消息被正确发送,但是第一次调用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
答案 0 :(得分:0)
好的,我能够解决这个问题。 _unauthorizedResponse
类变量以某种方式允许代码成功运行一次,但不是第二次。此问题与readonly修饰符无关,因为没有它它仍然无法正常工作。我不确定这是如何工作的(也许这里有人可以解释),但是通过将它们移动到方法中的局部范围内,它每次都能正确运行。