使用 Web API 对 JWT 令牌进行单元测试

问题描述 投票:0回答:1

我正在尝试使用 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/其他方式触发处理程序,则不会引发异常,并且一切正常。

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
1个回答
0
投票

我不会这样做。

在这种情况下我所做的是编写涵盖令牌逻辑的集成测试。

这意味着调用令牌端点,检索令牌,然后调用其他内容并看看会发生什么。

然后,您可以添加其他测试,例如令牌丢失、无效、已过期或包含错误声明时会发生什么情况。

© www.soinside.com 2019 - 2024. All rights reserved.