2014-10-24 37 views
5

Per SharePoint 2010 abbiamo utilizzato servizi Web personalizzati (NON SOAP!) Per rendere disponibili alcuni dati di terze parti al codice JS nelle pagine visualizzate dal browser. Si trattava di dati sensibili, quindi abbiamo utilizzato la rappresentazione per garantire che solo gli utenti giusti potessero accedervi. La nostra soluzione non funziona più in SharePoint 2013. Poiché la soluzione originale è piuttosto complessa, ho creato un servizio piccolo e semplice in SP 2013 per studiare come è possibile configurare un servizio Web con impersonificazione. Il servizio viene distribuito in una sottocartella di ISAPI.Servizio Web personalizzato in SharePoint 2013 con rappresentazione

Questa è la base senza la rappresentazione, che funziona:

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" %> 

Il codice dietro in 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; 
     } 
    } 
} 

Quando mi esibisco a GET su http://pc00175/_vti_bin/Sandbox/TestService.svc/GetAllNumbers Ricevo la risposta prevista [1,1,2,3,5,8,13]. Bene finora. Ora cerco di utilizzare la rappresentazione: "Un'identità anonimo non può eseguire una rappresentazione"

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

Ora ho uno System.InvalidOperationException con il messaggio quando si effettua la chiamata a ServiceSecurityContext.Current.WindowsIdentity.Impersonate(). Devo dire alla WCF che abbiamo bisogno della rappresentazione per quella chiamata. Così ho aggiunto un attributo [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; 
     } 
    } 
} 

ora trovo il seguente errore nel registro di 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... 

Poi ho capito che ho dovuto aggiungere un web.config accanto TestService.svc e aggiungi modalità TransportCredentialsOnly ma questo non ha aiutato:

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

ottengo lo stesso errore nel file di registro di SharePoint.

Spero che qualcuno abbia un suggerimento per me.

Grazie per aver letto fino a qui!

Peter

risposta

0

Se si desidera utilizzare REST, perché non è sufficiente a creare un app per questo? È molto più semplice dell'esporre un servizio WCF in SharePoint. È quindi possibile configurare le proprie impostazioni di sicurezza.

Questo article dovrebbe essere d'aiuto.

+0

Grazie per il suggerimento. Ho fatto un errore descrivendolo come servizio REST. È un servizio web generale. Non vogliamo riprogettare l'intera soluzione in quanto è piuttosto complessa e vorremmo mantenere le soluzioni SharePoint 2010 e 2013 il più simili possibile. –