3

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)

4

1 回答 1

2

按照“使用 ASP.NET 设计可演化的 Web API”中第 15 章的“检索和分配当前主体”部分中列出的指导,我取得了成功:

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

简而言之,在您的消息处理程序中,这样做而不是设置当前线程和 HttpContext 的主体:

request.GetRequestContext().Principal = principal;
于 2014-07-12T15:20:55.470 回答