SharePoint 2013 中的自定义 Web 服务与模拟

Posted

技术标签:

【中文标题】SharePoint 2013 中的自定义 Web 服务与模拟【英文标题】:Custom web service in SharePoint 2013 with impersonation 【发布时间】:2014-12-20 04:58:52 【问题描述】:

对于 SharePoint 2010,我们使用自定义 Web 服务(不是 SOAP!)使一些第 3 方数据可用于浏览器显示的页面中的 JS 代码。这是敏感数据,因此我们使用模拟来确保只有正确的用户才能访问它。我们的解决方案在 SharePoint 2013 中不再适用。由于原始解决方案非常复杂,我在 SP 2013 中构建了一个小型且简单的服务,以研究如何设置具有模拟的 Web 服务。该服务部署到 ISAPI 的子文件夹。

这是没有模仿的基础,有效:

TestService.svc:

<%@ ServiceHost 
    Language="C#"
    Debug="true" 
    Service="Sandbox.TestService, $SharePoint.Project.AssemblyFullName$" 
    CodeBehind="TestService.svc.cs" 
    Factory="Microsoft.SharePoint.Client.Services.MultipleBaseAddressWebServiceHostFactory, Microsoft.SharePoint.Client.ServerRuntime, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

TestService.svc.cs后面的代码是:

using Microsoft.SharePoint.Client.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Activation;
using System.ServiceModel;
using System.ServiceModel.Web;

namespace Sandbox

    [ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    public class TestService
    
        [OperationContract]
        [WebGet(UriTemplate = "GetAllNumbers",
            ResponseFormat = WebMessageFormat.Json)]
        List<int> GetAllNumbers()
        
            List<int> result = new List<int>();
            result.AddRange(new[]  1, 1, 2, 3, 5, 8, 13 );
            return result;
        
    

当我在 http://pc00175/_vti_bin/Sandbox/TestService.svc/GetAllNumbers 上执行 GET 时,我收到了预期的响应 [1,1,2,3,5,8,13]。到目前为止还好。现在我尝试使用模拟:

using Microsoft.SharePoint.Client.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Activation;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Security.Principal;

namespace Sandbox

    [ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    public class TestService
    
        [OperationContract]
        [WebGet(UriTemplate = "GetAllNumbers",
            ResponseFormat = WebMessageFormat.Json)]
        List<int> GetAllNumbers()
        
            List<int> result = new List<int>();
            WindowsImpersonationContext ctx = ServiceSecurityContext.Current.WindowsIdentity.Impersonate();
            try
            
                result.AddRange(new[]  1, 1, 2, 3, 5, 8, 13 );
            
            finally
            
                ctx.Undo();
            
            return result;
        
    

现在我收到 System.InvalidOperationException 消息“匿名身份无法执行模拟”。拨打ServiceSecurityContext.Current.WindowsIdentity.Impersonate() 时。我需要告诉 WCF 我们需要模拟该呼叫。于是我加了一个属性[OperationBehavior(Impersonation=ImpersonationOption.Required)]

using Microsoft.SharePoint.Client.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Activation;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Security.Principal;

namespace Sandbox

    [ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    public class TestService
    
        [OperationContract]
        [WebGet(UriTemplate = "GetAllNumbers",
            ResponseFormat = WebMessageFormat.Json)]
        [OperationBehavior(Impersonation=ImpersonationOption.Required)]
        List<int> GetAllNumbers()
        
            List<int> result = new List<int>();
            WindowsImpersonationContext ctx = ServiceSecurityContext.Current.WindowsIdentity.Impersonate();
            try
            
                result.AddRange(new[]  1, 1, 2, 3, 5, 8, 13 );
            
            finally
            
                ctx.Undo();
            
            return result;
        
    

现在我在 SharePoint 日志中发现以下错误:

Error when open web service: System.InvalidOperationException: The contract operation 'GetAllNumbers' requires Windows identity for automatic impersonation. A Windows identity that represents the caller is not provided by binding ('WebHttpBinding','http://tempuri.org/') for contract ('TestService','http://tempuri.org/'.     at System.ServiceModel.Dispatcher.SecurityValidationBehavior.WindowsIdentitySupportRule.ValidateWindowsIdentityCapability(Binding binding, ContractDescription contract, OperationDescription operation)     at System.ServiceModel.Dispatcher.SecurityValidationBehavior.WindowsIdentitySupportRule.Validate(ServiceDescription description)     at System.ServiceModel.Dispatcher.SecurityValidationBehavior.System.ServiceModel.Description.IServiceBehavior.Validate(ServiceDescriptio...

然后我猜我必须在 TestService.svc 旁边添加一个 web.config 并添加 TransportCredentialsOnly 模式,但这没有帮助:

<?xml version="1.0"?>
<configuration>
  <system.serviceModel>
    <bindings>
      <webHttpBinding>
        <binding>
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Ntlm"/>
          </security>
        </binding>
      </webHttpBinding>
    </bindings>
  </system.serviceModel>
</configuration>

我在 SharePoint 日志文件中遇到同样的错误。

我希望有人能给我一些提示。

感谢您阅读本文!

彼得

【问题讨论】:

【参考方案1】:

如果您想使用 REST,为什么不简单地为此创建一个应用程序?这比在 SharePoint 中公开 WCF 服务要容易得多。然后,您可以配置自己的安全设置。

这个article 应该可以帮助你。

【讨论】:

感谢您的提示。我错误地将其描述为 REST 服务。它是一个通用的网络服务。我们不想重新设计整个解决方案,因为它非常复杂,我们希望尽可能保持 SharePoint 2010 和 2013 解决方案的相似性。

以上是关于SharePoint 2013 中的自定义 Web 服务与模拟的主要内容,如果未能解决你的问题,请参考以下文章

摘要链接 Web 部件与 SharePoint 2007/2010 中的自定义 Web 部件冲突

将自定义 Web 部件部署到 SharePoint 2013

SharePoint 中 Web 部件的自定义属性编辑器

CSS sharepoint 2007内容编辑器Web部件css语法的自定义类

Sharepoint 2013 中的 Ajax 连接 Web 部件

如何在 SharePoint 2013 中创建自定义优化面板