如何使用自定义身份验证和内存托管进行ASP.NET Web API集成测试 [英] How to do ASP.NET Web API integration tests with custom authentication and in-memory hosting

查看:145
本文介绍了如何使用自定义身份验证和内存托管进行ASP.NET Web API集成测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此处,我们已经回答了类似的问题,但是在我看来,这个答案似乎不起作用.

A similar question has been answered here but the answer doesn't seem to work in my case.

我想在使用JWT身份验证的Web Api中测试身份验证/授权过程.

I want to test the authentication/authorization process in my Web Api which is using a JWT authentication.

我的身份验证是通过添加到我的HttpConfiguration中的自定义MessageHandler处理的.授权由我要限制访问的控制器/方法上的简单[Authorize]属性处理.

My authentication is handled through a custom MessageHandler that I add to my HttpConfiguration. Authorization in handled by a simple [Authorize] Attribute on Controller/Methods I want to restrict access to.

我正在设置在身份验证期间通过令牌从我的令牌中提取的主体(在我的自定义MessageHandler中):

I'm setting the principal I've extracted from my token this way during authentication (in my custom MessageHandler):

Thread.CurrentPrincipal = principal;

if (HttpContext.Current != null)
{
     HttpContext.Current.User = principal;
}

当我在本地IIS中手动测试时,整个过程运行良好.

This whole process is working fine when I test it manually in a local IIS.

但是在使用内存托管(例如此处)进行测试时 存储用于与[Authorize]进行授权的Principal的ApiController.User属性在我的调用测试(当前会话的Windows主体)中获得Thread.CurrentPrincipal,而不是在身份验证过程中设置的一个. 如果将Thread.CurrentPrincipal设置为null,则只会收到错误的请求.

But when testing with an in-memory hosting like here The ApiController.User property storing the Principal that is used for authorization with [Authorize] get the Thread.CurrentPrincipal in my calling test (the windows principal of my current session) instead of the one set during authentication. If I set my Thread.CurrentPrincipal to null, I get only bad requests.

TL; DR 如何使用内存托管测试身份验证/授权管道 ?因为它在我的测试中将ApiController.User值设置为Thread.CurrentPrincipal值,但未获得在身份验证期间成功设置的值.

TL;DR How do I test my authentication/authorization pipeline with in memory hosting ? As it sets the ApiController.User value to the Thread.CurrentPrincipal value in my test and not getting the one I set successfully during authentication.

我认为我可以设法实现自定义[Authorize]属性而不是ApiController.User的自定义[Authorize]属性,但是我想避免这种情况.

I think I can manage to do a work around with implementing a custom [Authorize] Attribute getting the Thread.CurrentPrincipal and not the ApiController.User, but I'd like to avoid that.

谢谢.

编辑进行澄清:所有这些管道(先认证然后授权)都可以在运行中的IIS中正常运行(在内存托管期间HttpContext为空).我只是想在内存托管中测试它(如果可能的话).在内存托管测试中,在我的自定义MessageHandler中放置了断点,我可以说Thread.CurrentPrincipal设置正确,只是[Authorize]似乎并不在意,因为在我的ApiControllers中,ApiController.User属性已在测试中设置为我的Thread.CurrentPrincipal值(我的本地Windows会话主体)

EDIT for clarification: all this pipeline (authentication then authorization) is working fine hosted in a running IIS (with an HttpContext which is null during in memory hosting). I'm just trying to test it with in memory hosting (if it is possible). During testing with in memory hosting , putting breakpoints in my custom MessageHandler, I can tell that the Thread.CurrentPrincipal is well set, it's just that [Authorize] doesn't seem to care about that, as, in my ApiControllers the ApiController.User property is already set to the value of my Thread.CurrentPrincipal value in my test (my local Windows session principal)

推荐答案

我已经成功完成了:

在ASP.NET Web API版本2.0中,可以通过使用以下方法解决此问题 新的HttpRequestContext类.首先,当前身份应 检索并分配给当前请求对象,而不是分配给 静态属性.其次,不同的主机可以使用不同的 HttpRequestContext实现

In ASP.NET Web API version 2.0, you can solve this problem by using the new HttpRequestContext class. First, the current identity should be retrieved and assigned to the current request object, not to a static property. Secondly, different hosts can use different HttpRequestContext implementations

简而言之,在您的消息处理程序中,执行此操作,而不是设置当前的Thread和HttpContext的主体:

In short, in your message handler, do this instead of setting the current Thread and HttpContext's principal:

request.GetRequestContext().Principal = principal;

这篇关于如何使用自定义身份验证和内存托管进行ASP.NET Web API集成测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆