我有一个C#MVC项目,我最近添加了WebApi。我已使用HMAC身份验证保护API,并使用CustomDelegatingHandler将授权添加到请求的标头。
我已经使用相同的代码在另一个项目上成功完成了这项工作。但是在这个新项目中,身份验证只能运行一次,然后由于" Unauthorized"而对API的每次其他调用都会失败。这只发生在我们的开发/测试服务器上,而不是在我在Visual Studio 2017中运行项目的本地机器上。
什么可能导致这种奇怪的行为?
以下是我使用的CustomDelegatingHandler:
public class CustomDelegatingHandler : DelegatingHandler
{
private string APPId = "";
private string APIKey = "";
public CustomDelegatingHandler(string appid, string apikey)
{
APPId = appid;
APIKey = apikey;
}
protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
HttpResponseMessage response = null;
string requestContentBase64String = string.Empty;
string requestUri = System.Web.HttpUtility.UrlEncode(request.RequestUri.AbsoluteUri.ToLower());
string requestHttpMethod = request.Method.Method;
//Calculate UNIX time
DateTime epochStart = new DateTime(1970, 01, 01, 0, 0, 0, 0, DateTimeKind.Utc);
TimeSpan timeSpan = DateTime.UtcNow - epochStart;
string requestTimeStamp = Convert.ToUInt64(timeSpan.TotalSeconds).ToString();
//create random nonce for each request
string nonce = Guid.NewGuid().ToString("N");
//Checking if the request contains body, usually will be null wiht HTTP GET and DELETE
if (request.Content != null)
{
byte[] content = await request.Content.ReadAsByteArrayAsync();
MD5 md5 = MD5.Create();
//Hashing the request body, any change in request body will result in different hash, we'll incure message integrity
byte[] requestContentHash = md5.ComputeHash(content);
requestContentBase64String = Convert.ToBase64String(requestContentHash);
}
//Creating the raw signature string
string signatureRawData = String.Format("{0}{1}{2}{3}{4}{5}", APPId, requestHttpMethod, requestUri, requestTimeStamp, nonce, requestContentBase64String);
var secretKeyByteArray = Convert.FromBase64String(APIKey);
byte[] signature = Encoding.UTF8.GetBytes(signatureRawData);
using (HMACSHA256 hmac = new HMACSHA256(secretKeyByteArray))
{
byte[] signatureBytes = hmac.ComputeHash(signature);
string requestSignatureBase64String = Convert.ToBase64String(signatureBytes);
//Setting the values in the Authorization header using custom scheme (amx)
request.Headers.Authorization = new AuthenticationHeaderValue("amx", string.Format("{0}:{1}:{2}:{3}", APPId, requestSignatureBase64String, nonce, requestTimeStamp));
}
response = await base.SendAsync(request, cancellationToken);
return response;
}
}
答案 0 :(得分:2)
我们遇到了类似的问题,结果与客户端与服务器的时间戳有关。
通过以这种方式检查请求是否在允许的时间内来解决它(服务器端):
(a > b ? a-b : b-a) > maxtime
vs a - b > maxtime
如果b> a,作为无符号长整数(ulong),该值变为巨大值,从而触发无效请求条件。
1522896501 - 1522896502&gt; 300(18446744073709551615是计算的)