问题
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