【发布时间】:2018-12-23 11:56:47
【问题描述】:
我正在尝试使用 Web API2、JWT、Microsoft.IdentityModel.JsonWebTokens 5.2.422 和本文所述的令牌验证逻辑:http://www.decatechlabs.com/secure-webapi-using-jwt
当我重复本文中的步骤(包括通过 Restlet 测试 API)时,一切对我的项目都很有效。但是,我正在尝试对这个项目使用测试驱动开发 (TDD),理想情况下,我想测试我的测试中的一切是否正常,包括令牌验证处理程序。如果我在单元测试中直接调用它们,我可以测试我的控制器,但这绕过了实际的令牌验证处理程序。因此,我尝试使用自托管 HTTP 来正确执行完整的 API,包括所有令牌验证处理程序逻辑。这是我获取令牌然后将令牌传递给需要授权的第二种方法的完整单元测试:
[TestMethod]
public void GetAuthorizedStatus_SelfHostedHTTP()
{
HttpServer server = TestAPIHelper.GenerateTestServer();
using (HttpMessageInvoker client = new HttpMessageInvoker(server))
{
string token = string.Empty;
using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, loginURL))
{
var stringContent = new StringContent(JsonConvert.SerializeObject(TestAPIHelper.loginObject), Encoding.UTF8, "application/json");
request.Content = stringContent;
using (HttpResponseMessage response = client.SendAsync(request, System.Threading.CancellationToken.None).Result)
{
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode, "Error getting token from login portion");
token = response.Content.ReadAsAsync<string>().Result;
Assert.IsTrue(token.Length > 50);
}
}
using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, authorizedStatusURL))
{
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
using (HttpResponseMessage response = client.SendAsync(request, System.Threading.CancellationToken.None).Result)
{
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode, "Error getting status from Authenticated portion.");
}
}
};
}
问题在于 TokenValidationHandler 抛出“对象引用未设置为对象的实例”。处理程序下面两行中的第二行的异常,仅当我的单元测试调用并附加了令牌时。如果我使用 Restlet/Postman/whatever 触发处理程序,则不会引发异常并且一切正常。
Thread.CurrentPrincipal = handler.ValidateToken(token, validationParameters, out securityToken);
HttpContext.Current.User = handler.ValidateToken(token, validationParameters, out securityToken);
当第一行几乎相同的行工作时,我不明白是什么导致第二行出错 - 两行都调用相同的方法。而且我不明白为什么它可以与第三方软件一起使用,但不能与我的测试代码一起使用——我担心的是,如果我不为单元测试解决这个问题,那么我将无法让代码为调用此 api 的真实应用程序。我认为这是我的测试代码中的一些琐碎设置,我需要在提交之前添加到我的请求中。但也许我需要在我的单元测试中构建一种完全不同的调用 API 的方法。
【问题讨论】:
标签: c# unit-testing asp.net-web-api2 jwt tdd