gpt4 book ai didi

asp.net - Thread.CurrentPrincipal 未在使用 WebGet 调用的 WCF 服务中设置

转载 作者:行者123 更新时间:2023-12-04 01:08:33 24 4
gpt4 key购买 nike

我有一个托管在 IIS 中的网站,它使用 Windows 身份验证并公开 WCF Web 服务。

我使用端点行为配置此服务:

<serviceAuthorization principalPermissionMode ="UseAspNetRoles" 
roleProviderName="MyRoleProvider"/>

和绑定(bind):
 <security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm" />
</security>

调用服务时, Thread.CurrentPrincipal设置为 RolePrincipal由配置的提供程序提供的客户端的 Windows 身份和角色。

世界一切安好。

现在,我添加了一些由 REST-ful Ajax 调用使用的额外 WCF 服务: Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory"在 svc 文件中, WebGet服务契约(Contract)中的属性,以及 AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)服务实现的属性。

我还按照 MSDN 中的建议将以下咒语添加到 web.config:
<system.serviceModel>
...
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
...
</system.serviceModel>

我的 Ajax 服务几乎按照我想要的方式工作。当它被调用时, HttpContext.Current.User设置为 RolePrincipal与我期望的角色。但是 Thread.CurrentPrincipal仍然设置为未经身份验证的 GenericPrincipal .

所以我需要在我的每个服务方法中添加一行代码:
Thread.CurrentPrincipal = HttpContext.Current.User

配置文件中有什么咒语可以用来获取 Thread.CurrentPrincipal自动设置,就像普通的 SOAP 服务一样?

更新
Here's来自有同样问题的人的博客,并通过实现自定义行为来解决它。当然有一种方法可以开箱即用吗?

更新 2
回来为此添加赏金,因为它在一个新项目中再次困扰我,在 .NET 3.5 上使用支持 WCF WebGet 的服务。

我尝试了许多选项,包括设置 principalPermissionMode="None",但没有任何效果。这是发生的事情:
  • 我导航到调用我的服务的 WebGet URL:http://myserver/MyService.svc/...
  • 我在 Global.asax "Application_AuthorizeRequest"中设置了一个断点。命中此断点时,“HttpContext.Current.User”和“Thread.CurrentPrincipal”都已设置为使用我配置的 ASP.NET RoleProvider 的“RolePrincipal”。这是我想要的行为。
  • 当我的服务的 OperationContract 方法被调用时,我有第二个断点。命中此断点时,HttpContext.Current.User 仍然引用我的 RolePrincipal,但 Thread.CurrentPrincipal 已更改为 GenericPrincipal。啊。

  • 我看到了对 implement a custom IAuthorizationPolicy 的建议,如果我没有找到更好的解决方案,我会调查,但为什么我需要实现自定义策略来利用现有的 ASP.NET 授权功能?如果我有 principalPermissionMode = "UseAspNetRoles",WCF 应该知道我想要什么吗?

    最佳答案

    这是个有趣的问题。我没有与您相同的设置,因此很难测试我的建议是否完全适用于您的用例,但我可以与类似项目分享对我们有用的东西。

    我们如何保持 Thread.CurrentPrincipalHttpContext.Current.User同步中

    我们编写了一个名为“AuthenticationModule”的HttpModule,它继承自IHtppModule。 .

    然后我们附加到 HttpApplication.AuthenticateRequest在请求生命周期的早期发生的事件。

    在我们的 AuthenticateRequest 事件处理程序中,我们实现了应用程序的特定要求,包括设置 Thread.CurrentPrincipal如有必要,还包括当前上下文用户。通过这种方式,您只需为整个应用程序实现此代码一次,如果它发生更改(例如,如果您实现自定义 Principal IIDentity),您只有一个地方可以更改它。 (不要在每个服务方法中重复此代码。)

    public class AuthenticationModule : IHttpModule
    {
    public void Dispose() { return; }

    public void Init(HttpApplication app)
    {
    app.AuthenticateRequest += new EventHandler(app_AuthenticateRequest);
    }

    void app_AuthenticateRequest(object sender, EventArgs e)
    {
    HttpApplication app = (HttpApplication)sender;

    // This is what you were asking for, but hey you
    // could change this behavior easily.
    Thread.CurrentPrincipal = app.Context.User;
    }
    }

    当我们实现自定义 IIdentity 时,我们的实际上有点复杂。 , 创建 GenericPrincipal 的实例然后将其分配给 app.Context.UserThread.CurrentPrincipal ;但是,以上是您所要求的。

    不要忘记在您的 web.config 中注册您的新 HttpModule !

    对于集成应用程序池:
    <system.webServer>
    <modules>
    <add name="AuthenticationModule" type="YourNameSpace.AuthenticationModule" preCondition="integratedMode" />
    </modules>
    </system.webServer>

    对于旧的经典应用程序池,您必须将其放入 <system.web><httpModules></httpModules></system.web>
    您可能需要使用 AuthenticationRequest 事件处理程序中的内容和/或注册处理程序的顺序。因为我们是完全定制的,所以它可能与您需要的不同。我们实际上获取了表单例份验证 cookie,对其进行解密等...您可能需要 ping 一些 WindowsAuthentication 的内置方法。

    我相信这是一种更通用的方式来处理您的应用程序身份验证内容,因为它适用于所有 HttpRequests是否是页面请求, IHttpHandler ,一些 3rd 方组件等...这将在您的整个应用程序中保持一致。

    关于asp.net - Thread.CurrentPrincipal 未在使用 WebGet 调用的 WCF 服务中设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9030125/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com