2010-05-04 13 views
47

Estoy integrando el servicio web que utilizará un HTTP-POST para solicitar y recuperar datos. El servidor remoto requiere autenticación básica según RFC 2617Forzar la autenticación básica en WebRequest

Mis intentos de autenticación están fallando.

Se produce un error en el que, a pesar de que hay que adjuntar un objeto 'NetworkCredential' para la propiedad 'credenciales' de un objeto 'HttpWebRequest', sin información de autenticación se envía en la cabecera, incluso si fijo 'PreAuthenticate' = true .

¿Qué me estoy perdiendo?

// trozo utiliza

NetworkCredential netCredential = new NetworkCredential(" uid", "pwd"); 

Uri uri = new Uri("http://address of services"); 

ICredentials credentials = netCredential.GetCredential(uri, "Basic"); 

objRegistration.Credentials = credentials; 

objRegistration.PreAuthenticate = true; 
+3

De MSDN: [ 'WebRequest.PreAuthenticate'] (http://msdn.microsoft.com/en-us/library/system.net.webrequest.preauthenticate(v=vs.110).aspx): ** Con la excepción de la primera solicitud ** _, ' La propiedad PreAuthenticate' indica si se debe enviar información de autenticación con ** solicitudes ** subsiguientes sin esperar a ser cuestionada por el servidor_, y ['HttpWebRequest.PreAuthenticate'] (http://msdn.microsoft.com/en-us/library/ system.net.httpwebrequest.preauthenticate (v = vs.110) .aspx): ** Después de ** _una solicitud del cliente a un Uri específico es autenticado con éxito, si 'PreAuthenticate' es verdadero ..._ – Sepster

Respuesta

107

Acabo de encontrar esta muy pequeño y práctico chunk of code para hacer exactamente lo que necesita. Agrega el encabezado de autorización al código manualmente sin esperar el desafío del servidor.

public void SetBasicAuthHeader(WebRequest request, String userName, String userPassword) 
{ 
    string authInfo = userName + ":" + userPassword; 
    authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo)); 
    request.Headers["Authorization"] = "Basic " + authInfo; 
} 

utilizar de esta manera

var request = WebRequest.Create("http://myserver.com/service"); 
SetBasicAuthHeader(request, userName, password); 

var response = request.GetResponse(); 
+0

parece que hay una mejor manera, pero lo votaré de todos modos;) –

+0

Esta es la respuesta correcta, no sé de lo que Himanshu está hablando. – cgatian

+0

¿Pero por qué no funciona sin esto? – Vedran

2

Aquí está mi solución para OAuth. El valor está en la variable json.

var myUri = new Uri(fullpath); 
var myWebRequest = WebRequest.Create(myUri); 
var myHttpWebRequest = (HttpWebRequest)myWebRequest; 
myHttpWebRequest.PreAuthenticate = true; 
myHttpWebRequest.Headers.Add("Authorization", "Bearer " + AccessToken); 
myHttpWebRequest.Accept = "application/json"; 

var myWebResponse = myWebRequest.GetResponse(); 
var responseStream = myWebResponse.GetResponseStream(); 
if (responseStream == null) return null; 

var myStreamReader = new StreamReader(responseStream, Encoding.Default); 
var json = myStreamReader.ReadToEnd(); 

responseStream.Close(); 
myWebResponse.Close(); 
2

me encontré con esta pregunta en la búsqueda de la respuesta, las obras Respuesta pero no es flexible por lo que si desea una mejor manera de hacer esto .NET.

Uri uri = new Uri("http://address of services"); 

HttpWebRequest objRegistration = (HttpWebRequest)WebRequest.Create(url); 

CredentialCache credentials = new CredentialCache(); 

NetworkCredential netCredential = new NetworkCredential(" uid", "pwd"); 

credentials.Add(uri, "Basic", netCredential); 

objRegistration.Credentials = credentials; 

Puede reemplazar "básico" con "NTLM" o "negociar", así como este da la posibilidad de añadir varios tipos a la caché, así "Digest".

+0

No diría que este método es más flexible , o una mejor .Net manera. Establecer el tipo de autenticación y las credenciales en CredentialCache no parece afectar/establecer el encabezado "Autorización" directamente. El ajuste de CredentialCache no ayudará en la situación mencionada anteriormente (cuando no hay desafío/código de estado 401 del servidor). – Denis

7

Mejorando un poco la respuesta aceptada de samuel-jack. En lugar de utilizar la codificación predeterminada "ISO-8859-1" debe ser utilizado como se menciona en esta respuesta What encoding should I use for HTTP Basic Authentication?

Así que el código se vería así:

public void SetBasicAuthHeader(WebRequest request, String userName, String userPassword) 
{ 
    string authInfo = userName + ":" + userPassword; 
    authInfo = Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes(authInfo)); 
    request.Headers["Authorization"] = "Basic " + authInfo; 
} 
Cuestiones relacionadas