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

发布于 2024-08-15 14:55:27 字数 980 浏览 5 评论 0原文

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

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

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

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

I have a per-call WCF service that's being hosted in IIS (.svc). In the service's constructor, I set Thread.CurrentPrincipal = HttpContext.Current.User as per this article. In this case HttpContext.Current.User is of type Microsoft.IdentityModel.Claims.ClaimsPrincipal and has the claims that were sent back from my custom passive STS.

However, as soon as I step into my service operation and examine Thread.CurrentPrincipal, while this object is still of type Microsoft.IdentityModel.Claims.ClaimsIdentity, the object itself is no longer the same as HttpContext.Current.User (IsAuthenticated = false, AuthenticationType = "" and Name is null on Thread.CurrentPrincipal.Identity), whereas these values are all still filled in correctly on HttpContext.Current.User. This tells me that something is intercepting the call to the operation and incorrectly changing the current principal to some generic, empty, unauthenticated claims principal.

I checked the thread ID in the constructor as well as in the operation and it's the same in both places, and evaluating Thread.CurrentPrincipal in the immediate window after assigning from HttpContext.Current.User shows that the thread identity is being set correctly in the constructor, so something is definitely executing in between the constructor and the method, and that something is changing my Thread.CurrentPrincipal.

Does anybody have any idea what is doing this, and how I can go about preventing / fixing this behaviour?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

岁月打碎记忆 2024-08-22 14:55:27

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

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

这对我来说效果很好。

I just ran into a similar problem. I set my custom principal in the constructor of my WCF service. When I left the constructor, and entered the method I called, the thread.currentprincipal was overridden by an empty one. I solved this by adding the following behavior:

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

This worked fine for me.

夏天碎花小短裙 2024-08-22 14:55:27

为 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 现在可以按预期工作。

When configuring a service for WIF federation, you call

FederatedServiceCredentials.ConfigureServiceHost(this);

Part of what this call does is to set up a custom ServiceAuthorizationManager of type IdentityModelServiceAuthorizationManager on the service host. This authorization manager appears to get called in between activation (construction) of the instance and execution of the operation, and it overwrites Thread.CurrentPrincipal with an instance of IClaimsPrincipal, but it doesn't seem to realize that it's running in ASP.NET Compatibility mode, so it doesn't pull the principal from HttpContext.Current.User.

I was able to bypass this behaviour by deriving from IdentityModelServiceAuthorizationManager and overriding the CheckAccess method as follows:

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

This then gets applied to the service host as follows:

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

And now when I enter my service operation, I have the correct IClaimsPrincipal on Thread.CurrentPrincipal, so declarative PrincipalPermission now works as expected.

微暖i 2024-08-22 14:55:27

调用的配置设置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" />

confguration settings for call FederatedServiceCredentials.ConfigureServiceHost(this);

is as below
in system.serviceModel add following

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

under inside add folowing line

<behavior name="serviceBehavior">
          <federatedServiceHostConfiguration name="MyService" />
ζ澈沫 2024-08-22 14:55:27

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

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

My guess is that nothing is intercepting the call. Either the CurrentPrincipal is reset by the time you're examining it or you're in a different thread.

Check the CurrentPrincipal immediately after assigning to it and you should see the correct value.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文