在声明身份验证的 SharePoint 2010 中托管的 WCF 服务中的模拟

Posted

技术标签:

【中文标题】在声明身份验证的 SharePoint 2010 中托管的 WCF 服务中的模拟【英文标题】:Impersonation in WCF service hosted in Claims-authenticated SharePoint 2010 【发布时间】:2011-07-21 06:49:39 【问题描述】:

我有一个 WCF 服务,它使用带有消息安全性和 Windows 身份验证的 wsHttpBinding。

控制台应用程序服务客户端能够调用该服务,我可以看到 ServiceSecurityContext.Current.WindowsIdentity 和 Thread.CurrentPrincipal.Identity 都代表正确的用户。

正如预期的那样,currentprincipal 是一个 IClaimsIdentity。

当我尝试打开 SharePoint 网站时出现问题:我收到拒绝访问错误,提示无法将模拟身份传递到数据库或共享点服务器。不过,这一切都在同一台机器上,所以不应该有任何双跳身份验证问题。

这不是对声明应用程序中托管的服务进行无头身份验证的正确方法吗?

【问题讨论】:

如何打开 SP 网页?您是否使用接受 SPUserToken 的构造函数重载? 我也试过了。看来我的 IClaimsIdentity 是 Microsoft.IdentityModel.WindowsClaimsIdentity,而不是 Microsoft.IdentityModel.ClaimsIdentity。如果 IClaimsIdentity 对象不是 ClaimsIdentity,SharePoint 的 SPUserToken 构造函数将引发异常。 我猜你需要转换声明。您是否尝试过从 WindowsClaimsIdentity 实例化 ClaimsIdentity ? 是的,那没用。我还尝试从端点配置中删除联合扩展,并对服务使用普通 Windows 身份验证。这让我回到了权限被拒绝错误。在给定 windowsidentity 作为输入的情况下,尝试从 claimidentity 实例化 spusertoken 也会失败。 如果您只考虑普通 Windows 身份验证,您是否在 WCF 端配置了模拟 (msdn.microsoft.com/en-us/library/ms731090.aspx) ? 【参考方案1】:

我目前在支持声明的 SharePoint 2010 网站中部署了 WCF 服务。 WCF 服务没有什么花哨的,我使用提供的 Microsoft.SharePoint.Client.Services.MultipleBaseAddressBasicHttpBindingServiceHostFactory 作为 WCF 服务工厂。因此,我使用通过工厂提供的开箱即用的 BasicHttpBinding。

我的客户端 app.config 如下所示:

<configuration>
  <system.serviceModel>
    <bindings>
      <binding name="BasicHttpBinding_MyServices" closeTimeout="00:01:00"
        openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
        allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
        maxBufferSize="200524288" maxBufferPoolSize="200524288" maxReceivedMessageSize="200524288"
        messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
        useDefaultWebProxy="true">
        <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
          maxBytesPerRead="4096" maxNameTableCharCount="16384" />
        <security mode="TransportCredentialOnly">
          <transport clientCredentialType="Ntlm" proxyCredentialType="None" realm="" />
          <message clientCredentialType="UserName" algorithmSuite="Default" />
        </security>
      </binding>
    </bindings>
    <client>
      <endpoint address="http://localhost/_vti_bin/MyServices/MyService.svc"
        binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_MyServices"
        contract="ServiceClient.MyService.IMyService"
        name="BasicHttpBinding_IMyService" />
    </client>
  </system.serviceModel>
</configuration>

查看我的 Thread.CurrentPrincipal.Identity 时,它是正确的。这是我当前正在执行的用户的 ClaimsIdentity。然后我可以简单地打开一个新的 SPSite 实例,而无需创建或使用 SPUserToken。

需要注意的一个关键点是:在连接到 WCF 服务之前,我不会冒充我的身份。如果这是您正在执行的操作,除非您的 SharePoint 服务器与您的声明提供者建立了信任关系,否则它可能不会起作用。

【讨论】:

以上是关于在声明身份验证的 SharePoint 2010 中托管的 WCF 服务中的模拟的主要内容,如果未能解决你的问题,请参考以下文章

从基于 Sharepoint 声明的身份验证 Web 应用程序中的代码访问 Windows 共享

Sharepoint 区域身份验证不起作用

如何向 sharepoint 2010 中托管的 wcf 服务发出经过身份验证的请求?

SharePoint 使用客户端证书为没有 Active Directory 帐户的用户声明身份验证

Sharepoint 2010 自定义 Web 服务 - HTTP 请求未经客户端身份验证方案“Ntlm”授权

SharePoint 2010客户端对象模型 - 需要代理身份验证