ASP.Net WCF 服务的 Thread.CurrentPrincipal 被联合 (WIF) 环境中的某些拦截器丢弃

StackOverflow https://stackoverflow.com/questions/1932424

  •  20-09-2019
  •  | 
  •  

我有一个托管在 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 (Thread.CurrentPrincipal.Identity 上的 IsAuthenticated = false、AuthenticationType = "" 且名称为 null),而这些值仍然全部正确填写 HttpContext.Current.User. 。这告诉我,某些东西正在拦截对操作的调用,并错误地将当前主体更改为某些通用的、空的、未经身份验证的声明主体。

我检查了构造函数和操作中的线程 ID,它在两个地方都是相同的,并评估 Thread.CurrentPrincipal 在分配自后的立即窗口中 HttpContext.Current.User 显示在构造函数中正确设置了线程标识,因此肯定在构造函数和方法之间执行了某些操作,并且某些操作正在改变我的 Thread.CurrentPrincipal.

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

有帮助吗?

解决方案 2

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

FederatedServiceCredentials.ConfigureServiceHost(this);

此调用的部分作用是设置一个自定义 服务授权管理器 类型的 身份模型服务授权管理器 在服务主机上。该授权管理器似乎在实例的激活(构造)和操作的执行之间被调用,并且它覆盖 Thread.CurrentPrincipal 与一个实例 IC索赔委托人, ,但它似乎没有意识到它正在 ASP.NET 兼容模式下运行,因此它不会从中提取主体 HttpContext.Current.User.

我能够通过派生来绕过这种行为 身份模型服务授权管理器 并覆盖 检查访问 方法如下:

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();
}

现在当我进入我的服务操作时,我有正确的 IC索赔委托人Thread.CurrentPrincipal, ,如此声明式 校长许可 现在按预期工作。

其他提示

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

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

这对我来说效果很好。

呼叫的配置设置 FederatedServiceCredentials.ConfigureServiceHost(这);

如下所示 在 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" />

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top