Webclient / HttpWebRequest avec authentification de base renvoie 404 introuvable pour une URL valide

Edit: Je voulais revenir pour noter que le problème n’était pas du tout de mon côté, mais plutôt avec le code du côté de l’autre société.

J’essaie de créer une page en utilisant l’authentification de base. Je continue à recevoir une erreur 404 Page introuvable. Je peux copier et coller mon URL dans le navigateur et cela fonctionne très bien (si je ne suis pas déjà connecté à leur site, une fenêtre d’identification apparaît, sinon, cela ouvre ce que je veux qu’elle ouvre). Je dois être au bon endroit et authentifier, parce que je reçois un 401 (erreur non authentifiée) si je mets un nom d’utilisateur / mot de passe intempestif et que je reçois une erreur de serveur interne 500 si je passe un paramètre incorrect dans la chaîne de requête . J’ai essayé d’utiliser Webclient et HttpWebRequest, tous deux entraînant l’erreur 404 non trouvée.

Avec Webclient:

ssortingng url = "MyValidURLwithQuerySsortingng"; WebClient client = new WebClient(); Ssortingng userName = "myusername"; Ssortingng passWord = "mypassword"; ssortingng credentials = Convert.ToBase64Ssortingng(Encoding.ASCII.GetBytes(userName + ":" + passWord)); client.Headers[HttpRequestHeader.Authorization] = "Basic " + credentials; var result = client.DownloadSsortingng(url); Response.Write(result); 

Avec HttpWebRequest

 HttpWebRequest request = (HttpWebRequest)WebRequest.Create("MyValidURL"); ssortingng authInfo = "username:password"; authInfo = Convert.ToBase64Ssortingng(Encoding.Default.GetBytes(authInfo)); request.Headers.Add("Authorization", "Basic " + authInfo); request.Credentials = new NetworkCredential("username", "password"); request.Method = WebRequestMethods.Http.Get; request.AllowAutoRedirect = true; request.Proxy = null; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); Stream stream = response.GetResponseStream(); StreamReader streamreader = new StreamReader(stream); ssortingng s = streamreader.ReadToEnd(); Response.Write(s); 

 //BEWARE //This works ONLY if the server returns 401 first //The client DOES NOT send credentials on first request //ONLY after a 401 client.Credentials = new NetworkCredential(userName, passWord); //doesnt work //So use THIS instead to send credentials RIGHT AWAY ssortingng credentials = Convert.ToBase64Ssortingng( Encoding.ASCII.GetBytes(userName + ":" + password)); client.Headers[HttpRequestHeader.Authorization] = ssortingng.Format( "Basic {0}", credentials); 

Essayez de modifier la partie d’authentification de la requête Web Client pour:

 NetworkCredential myCreds = new NetworkCredential(userName, passWord); client.Credentials = myCreds; 

Alors faites votre appel, semble fonctionner correctement pour moi.

Cette partie du code a bien fonctionné pour moi:

  WebRequest request = WebRequest.Create(url); request.Method = WebRequestMethods.Http.Get; NetworkCredential networkCredential = new NetworkCredential(logon, password); // logon in format "domain\username" CredentialCache myCredentialCache = new CredentialCache {{new Uri(url), "Basic", networkCredential}}; request.PreAuthenticate = true; request.Credentials = myCredentialCache; using (WebResponse response = request.GetResponse()) { Console.WriteLine(((HttpWebResponse)response).StatusDescription); using (Stream dataStream = response.GetResponseStream()) { using (StreamReader reader = new StreamReader(dataStream)) { ssortingng responseFromServer = reader.ReadToEnd(); Console.WriteLine(responseFromServer); } } } 

Si cela fonctionne lorsque vous utilisez un navigateur et que vous transmettez ensuite votre nom d’utilisateur et votre mot de passe pour la première fois, cela signifie qu’une fois l’authentification terminée, l’en-tête de demande de votre navigateur est défini avec les valeurs d’authentification requirejses. demande est faite au serveur d’hébergement.

Commencez donc par inspecter Request Header (ceci peut être fait à l’aide des outils Web Developers). Une fois que vous avez défini ce qui est requirejs dans l’entête, vous pouvez le transmettre dans votre en-tête HttpWebRequest.

Exemple avec l’authentification Digest:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Security.Cryptography; using System.Text.RegularExpressions; using System.Net; using System.IO; namespace NUI { public class DigestAuthFixer { private static ssortingng _host; private static ssortingng _user; private static ssortingng _password; private static ssortingng _realm; private static ssortingng _nonce; private static ssortingng _qop; private static ssortingng _cnonce; private static DateTime _cnonceDate; private static int _nc; public DigestAuthFixer(ssortingng host, ssortingng user, ssortingng password) { // TODO: Complete member initialization _host = host; _user = user; _password = password; } private ssortingng CalculateMd5Hash( ssortingng input) { var inputBytes = Encoding.ASCII.GetBytes(input); var hash = MD5.Create().ComputeHash(inputBytes); var sb = new SsortingngBuilder(); foreach (var b in hash) sb.Append(b.ToSsortingng("x2")); return sb.ToSsortingng(); } private ssortingng GrabHeaderVar( ssortingng varName, ssortingng header) { var regHeader = new Regex(ssortingng.Format(@"{0}=""([^""]*)""", varName)); var matchHeader = regHeader.Match(header); if (matchHeader.Success) return matchHeader.Groups[1].Value; throw new ApplicationException(ssortingng.Format("Header {0} not found", varName)); } private ssortingng GetDigestHeader( ssortingng dir) { _nc = _nc + 1; var ha1 = CalculateMd5Hash(ssortingng.Format("{0}:{1}:{2}", _user, _realm, _password)); var ha2 = CalculateMd5Hash(ssortingng.Format("{0}:{1}", "GET", dir)); var digestResponse = CalculateMd5Hash(ssortingng.Format("{0}:{1}:{2:00000000}:{3}:{4}:{5}", ha1, _nonce, _nc, _cnonce, _qop, ha2)); return ssortingng.Format("Digest username=\"{0}\", realm=\"{1}\", nonce=\"{2}\", uri=\"{3}\", " + "algorithm=MD5, response=\"{4}\", qop={5}, nc={6:00000000}, cnonce=\"{7}\"", _user, _realm, _nonce, dir, digestResponse, _qop, _nc, _cnonce); } public ssortingng GrabResponse( ssortingng dir) { var url = _host + dir; var uri = new Uri(url); var request = (HttpWebRequest)WebRequest.Create(uri); // If we've got a recent Auth header, re-use it! if (!ssortingng.IsNullOrEmpty(_cnonce) && DateTime.Now.Subtract(_cnonceDate).TotalHours < 1.0) { request.Headers.Add("Authorization", GetDigestHeader(dir)); } HttpWebResponse response; try { response = (HttpWebResponse)request.GetResponse(); } catch (WebException ex) { // Try to fix a 401 exception by adding a Authorization header if (ex.Response == null || ((HttpWebResponse)ex.Response).StatusCode != HttpStatusCode.Unauthorized) throw; var wwwAuthenticateHeader = ex.Response.Headers["WWW-Authenticate"]; _realm = GrabHeaderVar("realm", wwwAuthenticateHeader); _nonce = GrabHeaderVar("nonce", wwwAuthenticateHeader); _qop = GrabHeaderVar("qop", wwwAuthenticateHeader); _nc = 0; _cnonce = new Random().Next(123400, 9999999).ToString(); _cnonceDate = DateTime.Now; var request2 = (HttpWebRequest)WebRequest.Create(uri); request2.Headers.Add("Authorization", GetDigestHeader(dir)); response = (HttpWebResponse)request2.GetResponse(); } var reader = new StreamReader(response.GetResponseStream()); return reader.ReadToEnd(); } 

}

Ensuite, vous pouvez l'appeler:

 DigestAuthFixer digest = new DigestAuthFixer(domain, username, password); ssortingng strReturn = digest.GrabResponse(dir); 

si URL est: http://xyz.rss.com/folder/rss puis domaine: http://xyz.rss.com (partie de domaine) dir: / folder / rss (rest de l'URL)

Vous pouvez également le renvoyer sous forme de stream et utiliser la méthode XmlDocument Load ().