How to do ASP.NET Web API integration tests with custom authentication and in-memory hosting

爷,独闯天下 提交于 2019-12-10 11:35:15

问题


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

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

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.

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;
}

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

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 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.

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.

Thanks in advance.

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)


回答1:


I have had success following the guidance listed in the "Retrieving and Assigning the Current Principal" section of Chapter 15 in "Designing Evolvable Web APIs with ASP.NET":

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

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

request.GetRequestContext().Principal = principal;


来源:https://stackoverflow.com/questions/22715958/how-to-do-asp-net-web-api-integration-tests-with-custom-authentication-and-in-me

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!