c# - La solicitud HTTP no está autorizada con el esquema de autenticación de cliente ''Ntlm'' El encabezado de autenticación recibido del servidor era ''NTLM''
.net sharepoint (10)
Sé que hay muchas preguntas similares en este aspecto, pero no pude encontrar ninguna para este tema en particular.
Un par de puntos, primero:
- No tengo control sobre nuestro servidor Sharepoint. No puedo modificar ninguna configuración de IIS.
- Creo que nuestra versión del servidor IIS es IIS 7.0.
- Nuestro servidor Sharepoint está anticipando solicitudes a través de NTLM.
- Nuestro servidor Sharepoint está en el mismo dominio que mi computadora cliente.
- Estoy usando .NET Framework 3.5, Visual Studio 2008
Intento escribir una aplicación de consola simple para manipular datos de Sharepoint mediante los servicios web de Sharepoint. He agregado la Referencia del servicio y la siguiente es mi 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>
Este es mi código:
static void Main(string[] args)
{
using (var client = new ListsSoapClient())
{
client.ClientCredentials.Windows.ClientCredential = new NetworkCredential("username", "password", "domain");
client.GetListCollection();
}
}
Cuando llamo a GetListCollection (), se lanza la siguiente MessageSecurityException :
The HTTP request is unauthorized with client authentication scheme ''Ntlm''.
The authentication header received from the server was ''NTLM''.
Con una WebException interna:
"The remote server returned an error: (401) Unauthorized."
He intentado varios enlaces y varios ajustes de código para tratar de autenticar correctamente, pero fue en vano. Voy a enumerar los de abajo.
Probé los siguientes pasos:
Usar un imitador de Win32 nativo antes de crear el cliente
using (new Impersonator.Impersonator("username", "password", "domain"))
using (var client = new ListsSoapClient())
{
client.ClientCredentials.Windows.ClientCredential = new NetworkCredential("dpincas", "password", "domain");
client.GetListCollection();
}
Esto produjo el mismo mensaje de error.
Configuración de TokenImpersonationLevel para mis credenciales de cliente
using (var client = new ListsSoapClient())
{
client.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
client.GetListCollection();
}
Esto produjo el mismo mensaje de error.
Usar el modo de seguridad = TransportCredentialOnly
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm" />
</security>
Esto dio como resultado un mensaje de error diferente:
The provided URI scheme ''https'' is invalid; expected ''http''.
Parameter name: via
Sin embargo, necesito usar https, así que no puedo cambiar mi esquema de URI.
He intentado algunas otras combinaciones que no puedo recordar, pero las publicaré cuando lo haga. Estoy realmente nervioso aquí. Veo muchos enlaces en Google que dicen "cambiar a Kerberos", pero mi servidor parece aceptar solo NTLM, no "negociar" (como diría si estuviera buscando Kerberos), así que lamentablemente no es una opción .
¿Alguna ayuda, amigos?
Visual Studio 2005
- Crear un nuevo proyecto de aplicación de consola en Visual Studio
- Agregue una "Referencia web" al servicio web Lists.asmx.
- Su URL probablemente se verá como:
http://servername/sites/SiteCollection/SubSite/_vti_bin/Lists.asmx
- Llamé a mi referencia web:
ListsWebService
- Su URL probablemente se verá como:
- Escriba el código en program.cs (aquí tengo una lista de problemas)
Aquí está el código.
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());
}
}
}
}
Visual Studio 2008
- Crear un nuevo proyecto de aplicación de consola en Visual Studio
- Haga clic derecho en Referencias y agregue referencia de servicio
- Ingrese la URL al servicio Lists.asmx en su servidor
- Ejemplo:
http://servername/sites/SiteCollection/SubSite/_vti_bin/Lists.asmx
- Ejemplo:
- Haga clic en Ir
- Haga clic en Aceptar
- Realice los siguientes cambios de código:
Cambie su archivo app.config de:
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
A:
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm"/>
</security>
Cambie su archivo program.cs y agregue el siguiente código a su función principal:
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();
Agregue las instrucciones de uso:
using [your app name].ServiceReference1;
using System.Xml;
Después de muchas pruebas y errores, seguidos por un período de estancamiento mientras esperaba la oportunidad de hablar con nuestros servidores, finalmente tuve la oportunidad de discutir el problema con ellos y les pregunté si no les importaría cambiar nuestra autenticación Sharepoint. a Kerberos.
Para mi sorpresa, dijeron que esto no sería un problema y, de hecho, era fácil de hacer. Han habilitado Kerberos y he modificado mi app.config de la siguiente manera:
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
Como referencia, mi entrada de ServiceModel completa en mi app.config se ve así:
<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>
Después de esto, todo funcionó como un encanto. Ahora puedo (¡finalmente!) Utilizar Sharepoint Web Services. Por lo tanto, si alguien más no puede hacer que sus servicios web Sharepoint trabajen con NTLM, vea si puede convencer a los administradores del sistema para que cambien a Kerberos.
Después de muchas respuestas que no funcionaron, finalmente encontré una solución cuando el acceso anónimo está desactivado en el servidor IIS. Nuestro servidor usa autenticación de Windows, no Kerberos. Esto es gracias a esta publicación en el blog .
No se realizaron cambios en web.config.
En el lado del servidor, el archivo .SVC en la carpeta ISAPI utiliza MultipleBaseAddressBasicHttpBindingServiceHostFactory
Los atributos de clase del servicio son:
[BasicHttpBindingServiceMetadataExchangeEndpointAttribute]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class InvoiceServices : IInvoiceServices
{
...
}
En el lado del cliente, la clave que lo hizo funcionar fue la http atributos de seguridad vinculante:
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)
¡Espero que esto funcione para ti!
Este problema fue aún más extraño para nosotros. Todo funcionó si anteriormente había visitado el sitio sharepoint desde el navegador, antes de realizar la llamada SOAP. Sin embargo, si primero hicieras la llamada SOAP, arrojaríamos el error anterior.
Pudimos resolver este problema instalando el certificado de sharepoint en el cliente y agregando el dominio a los sitios de la intranet local.
He tenido este problema antes.
client.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
Haga esto contra su proxy wcf antes de hacer la llamada.
Intentaré conectarme a su sitio Sharepoint con esta herramienta here . Si eso funciona, puede estar seguro de que el problema está en su código / configuración. Eso tal vez no resuelva su problema de inmediato, pero descarta que haya algún problema con el servidor. Suponiendo que no funciona, investigaría lo siguiente:
- ¿Su usuario realmente tiene suficientes derechos en el sitio?
- ¿Hay un proxy que interfiere? (Su configuración se parece un poco a un proxy. ¿Puede eludirlo?)
Creo que no hay nada de malo en utilizar el modo de transporte de seguridad, pero no estoy tan seguro acerca de proxyCredentialType="Ntlm"
, quizás esto debería establecerse en Ninguno .
Prueba esto
<client>
<endpoint>
<identity>
<servicePrincipalName value="" />
</identity>
</endpoint>
</client>
He encontrado este error antes cuando trabajaba en una webfarm y esto lo solucionó.
Si recuerdo correctamente, hay algunos problemas con la adición de servicios web de SharePoint como VS2K8 "Referencia de servicio". Debe agregarlo como una "Referencia web" al estilo antiguo para que funcione correctamente.
Tengo la misma configuración que tú, y esto funciona bien para mí. Creo que tal vez el problema se encuentre en algún lugar de tu configuración de musgo o en tu red.
Dijiste que musgo reside en el mismo dominio que tu aplicación. Si tiene acceso al sitio con su usuario (que está conectado a su máquina) ... ha intentado:
client.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
Tuve exactamente el mismo problema la semana pasada: el programa WCF se comporta de manera extraña en un solo servidor. ¿Por qué?
Para mí, la solución fue bastante simple. Sharepoint tiene su propio conjunto de permisos. Mi cliente intentó iniciar sesión como un usuario que no recibió acceso explícito al servicio web a través del panel de administración de Sharepoint.
Agregué el usuario a la lista blanca y al bang de Sharepoint, simplemente funcionó.
Incluso si ese no es el problema, tenga en cuenta que
La solicitud HTTP no está autorizada con el esquema de autenticación de cliente ''Ntlm''. El encabezado de autenticación recibido del servidor era ''NTLM''.
Significa (en inglés) que simplemente no tiene permiso. Probablemente su protocolo sea correcto: su usuario simplemente no tiene permisos.