ASP.Net WCF服务';s Thread.CurrentPrincipal正在被联邦(WIF)环境中的某个拦截器丢弃

ASP.Net WCF服务';s Thread.CurrentPrincipal正在被联邦(WIF)环境中的某个拦截器丢弃,wcf,wif,claims,federation,Wcf,Wif,Claims,Federation,我有一个正在IIS(.svc)中托管的每次呼叫WCF服务。在服务的构造函数中,我根据设置Thread.CurrentPrincipal=HttpContext.Current.User。在本例中,HttpContext.Current.User的类型为Microsoft.IdentityModel.Claims.ClaimsPrincipal,并具有从自定义被动STS发回的声明 但是,只要我进入我的服务操作并检查Thread.CurrentPrincipal,而该对象仍然是Microsoft.I

我有一个正在IIS(.svc)中托管的每次呼叫WCF服务。在服务的构造函数中,我根据设置Thread.CurrentPrincipal=HttpContext.Current.User。在本例中,HttpContext.Current.User的类型为Microsoft.IdentityModel.Claims.ClaimsPrincipal,并具有从自定义被动STS发回的声明

但是,只要我进入我的服务操作并检查Thread.CurrentPrincipal,而该对象仍然是Microsoft.IdentityModel.ClaimsEntity类型,该对象本身就不再与HttpContext.Current.User相同(IsAuthenticated=false,AuthenticationType=“”在Thread.CurrentPrincipal.Identity上,Name为null,而在HttpContext.Current.User上,这些值仍然正确填写。这告诉我有什么东西正在拦截对操作的调用,并错误地将当前主体更改为一些通用的、空的、未经验证的声明主体

我检查了构造函数和操作中的线程ID,这两个位置都是相同的,从HttpContext.Current.User赋值后,在即时窗口中计算thread.CurrentPrincipal表明线程标识在构造函数中设置正确,因此,在构造函数和方法之间肯定有某种东西在执行,而且某种东西正在改变我的Thread.CurrentPrincipal


有人知道这是怎么回事吗?我该如何防止/纠正这种行为?

我猜没有人在拦截电话。当您检查CurrentPrincipal时,它会被重置,或者您处于不同的线程中


分配给CurrentPrincipal后立即检查它,您应该会看到正确的值。

为WIF联合配置服务时,您可以调用

FederatedServiceCredentials.ConfigureServiceHost(this);
此调用的部分作用是在服务主机上设置IdentityModelServiceAuthorizationManager类型的自定义ServiceAuthorizationManager。此授权管理器似乎在激活(构造)实例和执行操作之间被调用,它用ICLAIMSPRINCAL实例覆盖Thread.CurrentPrincipal,但它似乎没有意识到它正在ASP.NET兼容模式下运行,因此它不会从HttpContext.Current.User中提取主体

通过从IdentityModelServiceAuthorizationManager派生并重写CheckAccess方法,我可以绕过此行为,如下所示:

public class CustomAuthorizationManager : IdentityModelServiceAuthorizationManager
{
    public override bool CheckAccess(System.ServiceModel.OperationContext operationContext, ref System.ServiceModel.Channels.Message message)
    {
        var result = base.CheckAccess(operationContext, ref message);

        var properties = operationContext.ServiceSecurityContext.AuthorizationContext.Properties;
        properties["Principal"] = System.Web.HttpContext.Current.User;

        return result;
    }
}
protected override void InitializeRuntime()
{
    FederatedServiceCredentials.ConfigureServiceHost(this);
    this.Authorization.ServiceAuthorizationManager = new CustomAuthorizationManager();
    base.InitializeRuntime();
}
然后将其应用于服务主机,如下所示:

public class CustomAuthorizationManager : IdentityModelServiceAuthorizationManager
{
    public override bool CheckAccess(System.ServiceModel.OperationContext operationContext, ref System.ServiceModel.Channels.Message message)
    {
        var result = base.CheckAccess(operationContext, ref message);

        var properties = operationContext.ServiceSecurityContext.AuthorizationContext.Properties;
        properties["Principal"] = System.Web.HttpContext.Current.User;

        return result;
    }
}
protected override void InitializeRuntime()
{
    FederatedServiceCredentials.ConfigureServiceHost(this);
    this.Authorization.ServiceAuthorizationManager = new CustomAuthorizationManager();
    base.InitializeRuntime();
}

现在,当我进入我的服务操作时,我在Thread.CurrentPrincipal上有了正确的IClaimsPrincipal,因此声明性PrincipalPermission现在可以按预期工作。

为callFederatedServiceCredentials配置设置。配置ServiceHost(此

详情如下 在system.serviceModel中添加以下内容

<extensions>
      <behaviorExtensions>
        <add name="federatedServiceHostConfiguration" type="Microsoft.IdentityModel.Configuration.ConfigureServiceHostBehaviorExtensionElement, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      </behaviorExtensions>
    </extensions>

在“内部”下添加以下行

<behavior name="serviceBehavior">
          <federatedServiceHostConfiguration name="MyService" />

我刚刚遇到了类似的问题。我在WCF服务的构造函数中设置了自定义主体。当我离开构造函数并输入我调用的方法时,thread.currentprincipal被一个空的方法覆盖。我通过添加以下行为解决了此问题:

<serviceAuthorization principalPermissionMode="None"></serviceAuthorization>


这对我来说效果很好。

这个解决方案可以工作,但是我不确定现有IdentityModelServiceAuthorizationManager中是否存在错误-我的感觉是它应该能够判断它是在ASP.NET兼容模式下运行的,因此应该能够自动从HttpContext.Current.User中提取主体。在Microsoft发布Microsoft.IdentityModel 1.0.0.0之前,我是否应该将此作为错误报告给Microsoft?