4

我有一个托管在 IIS (.svc) 中的每次调用 WCF 服务。在服务的构造函数中,我按照本文设置了Thread.CurrentPrincipal = HttpContext.Current.User。在这种情况下, HttpContext.Current.User属于Microsoft.IdentityModel.Claims.ClaimsPrincipal类型,并且具有从我的自定义被动 STS 发回的声明。

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

我在构造函数和操作中检查了线程 ID,这两个地方都相同,并且在从HttpContext.Current.User分配后立即窗口中评估Thread.CurrentPrincipal表明线程标识在构造函数,所以在构造函数和方法之间肯定会执行某些东西,并且某些东西正在改变我的Thread.CurrentPrincipal

有谁知道这是在做什么,以及我该如何防止/修复这种行为?

4

4 回答 4

6

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

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

这对我来说很好。

于 2010-08-19T12:31:31.947 回答
3

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

FederatedServiceCredentials.ConfigureServiceHost(this);

此调用的部分作用是在服务主机上设置IdentityModelServiceAuthorizationManager类型的自定义ServiceAuthorizationManager 。此授权管理器似乎在实例的激活(构造)和操作的执行之间被调用,它用IClaimsPrincipal的实例覆盖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();
}

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

于 2009-12-22T09:00:21.170 回答
1

调用FederatedServiceCredentials.ConfigureServiceHost(this ) 的配置设置;

如下在 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" />
于 2010-03-29T07:13:32.730 回答
0

我的猜测是没有任何东西在拦截通话。CurrentPrincipal 要么在您检查它时被重置,要么您处于不同的线程中。

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

于 2009-12-19T09:58:46.513 回答