Je sais qu'il y a beaucoup de questions SO semblables à celles-ci, mais je n'ai pas pu en trouver une pour cette question particulière.
Quelques points, d’abord:
J'essaie d'écrire une application console simple pour manipuler les données Sharepoint à l'aide des services Web Sharepoint. J'ai ajouté la référence de service et voici mon app.config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="ListsSoap" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="Transport">
<transport clientCredentialType="Ntlm" proxyCredentialType="Ntlm" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://subdomain.companysite.com/subsite/_vti_bin/Lists.asmx"
binding="basicHttpBinding" bindingConfiguration="ListsSoap"
contract="ServiceReference1.ListsSoap" name="ListsSoap" />
</client>
</system.serviceModel>
Ceci est mon code:
static void Main(string[] args)
{
using (var client = new ListsSoapClient())
{
client.ClientCredentials.Windows.ClientCredential = new NetworkCredential("username", "password", "domain");
client.GetListCollection();
}
}
Lorsque j'appelle GetListCollection (), le message MessageSecurityException est renvoyé:
The HTTP request is unauthorized with client authentication scheme 'Ntlm'.
The authentication header received from the server was 'NTLM'.
Avec une exception WebException:
"The remote server returned an error: (401) Unauthorized."
J'ai essayé diverses liaisons et divers ajustements de code pour essayer de m'authentifier correctement, mais en vain. Je vais énumérer ceux ci-dessous.
Utilisation d'un imitateur Win32 natif avant de créer le client
using (new Impersonator.Impersonator("username", "password", "domain"))
using (var client = new ListsSoapClient())
{
client.ClientCredentials.Windows.ClientCredential = new NetworkCredential("dpincas", "password", "domain");
client.GetListCollection();
}
Cela a produit le même message d'erreur.
Définition de TokenImpersonationLevel pour les informations d'identification de mon client
using (var client = new ListsSoapClient())
{
client.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
client.GetListCollection();
}
Cela a produit le même message d'erreur.
Utilisation du mode de sécurité = TransportCredentialOnly
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm" />
</security>
Cela a entraîné un message d'erreur différent:
The provided URI scheme 'https' is invalid; expected 'http'.
Parameter name: via
Cependant, je dois utiliser https, je ne peux donc pas changer mon schéma d'URI.
J'ai essayé d'autres combinaisons dont je ne me souviens plus, mais je les posterai quand je le ferai. Je suis vraiment à la fin des esprits ici. Je vois beaucoup de liens sur Google qui disent "Basculer vers Kerberos", mais mon serveur semble n'accepter que NTLM, pas "Négocier" (comme il le ferait s'il cherchait Kerberos), ce qui n'est malheureusement pas une option .
Toute aide là-bas, les gens?
Après beaucoup d'essais et d'erreurs, suivis par une période stagnante pendant que j'attendais une occasion de parler à nos serveurs, j'ai enfin eu l'occasion de discuter du problème avec eux et je leur ai demandé s'ils souhaitaient changer d'authentification par Sharepoint vers Kerberos.
À ma grande surprise, ils ont dit que cela ne poserait pas de problème et que c'était en fait facile à faire. Ils ont activé Kerberos et j'ai modifié mon app.config comme suit:
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
Pour référence, mon entrée serviceModel complète dans mon application.config ressemble à ceci:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="TestServerReference" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="2000000" maxBufferPoolSize="2000000" maxReceivedMessageSize="2000000"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://path/to/site/_vti_bin/Lists.asmx"
binding="basicHttpBinding" bindingConfiguration="TestServerReference"
contract="TestServerReference.ListsSoap" name="TestServerReference" />
</client>
</system.serviceModel>
Après cela, tout a fonctionné comme un charme. Je peux maintenant (enfin!) Utiliser les services Web Sharepoint. Par conséquent, si quelqu'un d'autre ne parvient pas à faire fonctionner ses services Web Sharepoint avec NTLM, voyez si vous pouvez convaincre les administrateurs système de passer à Kerberos.
http://servername/sites/SiteCollection/SubSite/_vti_bin/Lists.asmx
ListsWebService
Voici le code.
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
namespace WebServicesConsoleApp
{
class Program
{
static void Main(string[] args)
{
try
{
ListsWebService.Lists listsWebSvc = new WebServicesConsoleApp.ListsWebService.Lists();
listsWebSvc.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
listsWebSvc.Url = "http://servername/sites/SiteCollection/SubSite/_vti_bin/Lists.asmx";
XmlNode node = listsWebSvc.GetList("Issues");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}
http://servername/sites/SiteCollection/SubSite/_vti_bin/Lists.asmx
Changez votre fichier app.config à partir de:
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
À:
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm"/>
</security>
Changez votre fichier program.cs et ajoutez le code suivant à votre fonction principale:
ListsSoapClient client = new ListsSoapClient();
client.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
XmlElement listCollection = client.GetListCollection();
Ajoutez les instructions using:
using [your app name].ServiceReference1;
using System.Xml;
Après de nombreuses réponses qui n'ont pas fonctionné, j'ai finalement trouvé une solution lorsque l'accès anonyme est désactivé sur le serveur IIS. Notre serveur utilise l'authentification Windows, pas Kerberos. C'est grâce à cet article de blog .
Aucune modification n'a été apportée à web.config.
Sur le serveur, le fichier .SVC du dossier ISAPI utilise MultipleBaseAddressBasicHttpBindingServiceHostFactory.
Les attributs de classe du service sont:
[BasicHttpBindingServiceMetadataExchangeEndpointAttribute]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class InvoiceServices : IInvoiceServices
{
...
}
Du côté du client, la clé qui l’a fait fonctionner était les attributs de sécurité de liaison HTTP:
EndpointAddress endpoint =
new EndpointAddress(new Uri("http://SharePointserver/_vti_bin/InvoiceServices.svc"));
BasicHttpBinding httpBinding = new BasicHttpBinding();
httpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
InvoiceServicesClient myClient = new InvoiceServicesClient(httpBinding, endpoint);
myClient.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
(call service)
J'espère que cela fonctionne pour vous!
Si je me souviens bien, l'ajout de services Web SharePoint en tant que "Référence de service" VS2K8 pose certains problèmes. Vous devez l'ajouter en tant que "référence Web" à l'ancienne pour fonctionner correctement.
Je voudrais essayer de vous connecter à votre site Sharepoint avec cet outil ici . Si cela fonctionne, vous pouvez être sûr que le problème vient de votre code/configuration. Cela ne résout peut-être pas votre problème immédiatement, mais cela exclut tout problème avec le serveur. En supposant que cela ne fonctionne pas, j'examinerais les points suivants:
Je pense qu'il n'y a rien de mal à utiliser le mode de sécurité Transport, mais je ne suis pas sûr du proxyCredentialType="Ntlm"
. Peut-être que ceci devrait être réglé sur None.
J'ai eu ce problème avant.
client.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
faites ceci contre votre proxy wcf avant de faire l'appel.
J'ai la même configuration que vous et cela fonctionne bien pour moi. Je pense que le problème réside peut-être quelque part dans votre configuration de mousse ou sur votre réseau.
Vous avez dit que la mousse réside sur le même domaine que votre application. Si vous avez accès au site avec votre utilisateur (connecté à votre ordinateur) ... avez-vous essayé:
client.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
J'ai eu exactement le même problème la semaine dernière - Le programme WCF se comporte étrangement sur un serveur - pourquoi?
Pour moi, la solution était plutôt simple. Sharepoint dispose de son propre ensemble d'autorisations. Mon client a essayé de se connecter en tant qu'utilisateur n'ayant pas explicitement accès au service Web via le panneau d'administration de Sharepoint.
J'ai ajouté l'utilisateur à la liste blanche et au bang de Sharepoint - cela fonctionnait.
Même si ce n'est pas le problème, veuillez noter que
La requête HTTP n’est pas autorisée avec le schéma d’authentification du client «Ntlm». L’en-tête d’authentification reçu du serveur était ‘NTLM’.
Signifie (en anglais) que vous n'avez tout simplement pas la permission. Votre protocole est probablement correct - votre utilisateur n’a tout simplement pas d’autorisations.
Essaye ça
<client>
<endpoint>
<identity>
<servicePrincipalName value="" />
</identity>
</endpoint>
</client>
J'ai déjà rencontré cette erreur lorsque je travaillais dans une ferme Web et cela a été corrigé.
Ce problème était encore plus étrange pour nous. Tout fonctionnait si vous aviez déjà visité le site SharePoint à partir du navigateur avant de passer l'appel SOAP. Cependant, si vous avez d'abord appelé SOAP, l'erreur ci-dessus est générée.
Nous avons pu résoudre ce problème en installant le certificat SharePoint sur le client et en ajoutant le domaine aux sites intranet locaux.