我们最近将一些旧代码从net 3.5迁移到了net 4.6.2。作为此过程的一部分,我们还从IIS中的经典模式转换为集成模式。该计划是不对代码本身进行功能上的更改,仅针对新框架并更改站点配置。
该网站使用一种模式,通过该模式我们通过Windows身份验证对用户进行身份验证,并创建具有其他属性的自定义主体,并在Application_AcquireRequestState
事件触发时将其附加到线程上;
var principal = new OurCustomPrincipal();
Thread.CurrentPrincipal = principal;
然后我们在其他地方使用此主体,如下所示;
var principal = Thread.CurrentPrincipal as OurCustomPrincipal;
if (principal == null)
throw exception;
在从经典更改为集成之前,此方法非常有效。使用集成模式时,我们开始注意到的是上面的主体为null,线程上的主体不是OurCustomerPrincipal,而是通用的Principal。
进一步的调查显示,正在发生的事情是在我们分配Thread.CurrentPrincipal的同时,额外的处理发生在另一个线程上,因此转换失败。
工作流程;
Click link on website
HttpModule - Authentication_AcquireRequestState and assign Thread.CurrentPrincipal (thread 1)
HttpHandler - Process request (thread 1)
非工作流程
Click link on website
HttpModule - Authentication_AcquireRequestState and assign thread.CurrentPrincipal (thread 1)
HttpHandler - Process request (thread 2)
在大多数情况下,何时工作以及何时不工作没有任何模式。
我们更改了实现,以将OurCustomPrincipal存储在HttpContext中,并且无论线程的差异如何都将保留该实现,但是在真正了解其原因之前,我们不愿将其从经典更改为集成到生产中。
研究尚未发现这种行为改变的任何明确原因,因此需要寻找可能的改变建议。