none
Credential : NTML + htaccess RRS feed

  • Question

  • Bonjour,
    J'ai un problème que je n'arrive pas à résoudre. J'essaie de réaliser une connexion via un objet HttpWebRequest sauf que je dois répondre à deux contraintes :
    - la connexion se fait via un proxy qui utilise le protocole NTML
    - la page web à laquelle je tente d'accéder est protégée par un login/pass via un fichier .htaccess

    Mon code pour la connexion est le suivant :

    Dim
     hwebrequest As
     System.Net.HttpWebRequest = CType
    (System.Net.HttpWebRequest.Create(url), HttpWebRequest)
    hwebrequest.Method = "GET"
    
    
    hwebrequest.Credentials = CredentialCache.DefaultCredentials
    hwebrequest.KeepAlive = True
    
    hwebrequest.PreAuthenticate = True
    
    hwebrequest.Headers.Set
    ("Pragma"
    , "no-cache"
    )
    
    'si la connexion se fait par un proxy
    
    If
     optionsINI.ReadBoolean("Connection"
    , "useProxy"
    ) Then
    
    	Dim
     proxy As
     New
     System.Net.WebProxy(optionsINI.ReadString("Connection"
    , "proxyAddress"
    ), Integer
    .Parse(optionsINI.ReadString("Connection"
    , "proxyPort"
    )))
    	If
     optionsINI.ReadBoolean("Connection"
    , "proxyAutoConfig"
    ) Then
    
    		proxy.Credentials = CredentialCache.DefaultCredentials
    	Else
    
    		proxy.Credentials = New
     System.Net.NetworkCredential(optionsINI.ReadString("Connection"
    , "proxyUsername"
    ), Crypt.DecryptString(optionsINI.ReadString("Connection"
    , "proxyPassword"
    ))).GetCredential(New
     Uri(optionsINI.ReadString("Connection"
    , "proxyAddress"
    )), "NTML"
    )
    	End
     If
    
    	hwebrequest.Proxy = proxy
    End
     If
    
    hwebrequest.Timeout = optionsINI.ReadInteger("Connection"
    , "timeout"
    )
    
    'si la page web est protégée par un htaccess
    
    If
     username <> ""
     Then
    
    	hwebrequest.Credentials = New
     System.Net.NetworkCredential(username, password)
    End
     If
    
    
    Return
     hwebrequest
    
    Ce code fonctionne bien avec le protocole NTML ainsi que pour une page web protégée par un htaccess, mais pas pour les deux cas en même temps.
    Je comprends bien que les lignes
    If
     username <> ""
     Then
    
    	hwebrequest.Credentials = New
     System.Net.NetworkCredential(username, password)
    End
     If
    
    
    
    qui permettent d'ajouter le login/pass du htaccess écrasent les credentials nécessaires pour le protocole NTML. Mais comment transmettre les deux credentials ?

    Merci d'avance pour votre aide
    Cordialement
    mardi 15 décembre 2009 20:06

Réponses

  • Bonsoir,

    Je pense que si personne n'a encore répondu, c'est peut-être parce que ton code est mis en vrac, tout simplement.
    Un peu de formatage n'aurait pas été de trop.
    Ensuite, on n'a pas l'erreur que tu obtiens quand tu executes ton code, ni même ce qui se passe, on sait juste que tu n'y arrives pas.

    Bon voyons voir.
    Tu dois te connecter en NTLM à ton Proxy avec un premier lot de Credential, et après fournir un 2eme lot de Credential pour ta page finale.
    Ca doit ressembler à ça :

    Dim proxy As New WebProxy("http://proxy:80/", True)
    
    ' Un des deux au choix suivant comment tu te logges sur ton proxy
    proxy.Credentials = New NetworkCredential("userId", "password", "Domain")
    proxy.Credentials = CredentialCache.DefaultCredentials
    
    hwebrequest.Proxy = proxy
    
    'Un des deux au choix
    hwebrequest.Credentials = CredentialCache.DefaultCredentials
    hwebrequest.Credentials = New System.Net.NetworkCredential(username, password)


    En général, ce genre de config est pour permettre de passer un firewall.
    Donc tu es en CredentialCache.DefaultCredentials pour le proxy, en gros ton account Windows, et en NetworkCredential pour la suite.

    Si cela ne fonctionne pas, essaie de voir laquelle des 2 connexions, celle au proxy ou celle à la page, ne fonctionne pas.

    Cordialement,

    Thomas

    Thomas Aimonetti - C# - Sharplog Engineering - http://www.sharplog.fr
    lundi 18 janvier 2010 20:40
  • Bonjour,

    KeepAlive te permet davoir une connexion persistante, à toi de voir si tu en as besoin.

    Pour PreAuthenticate : http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.preauthenticate.aspx
    Vu ton cas, je te conseillerai de le laisser, cela évite les aller-retour inutiles entre le proxy et toi.

    Quant au header no-cache, il te permet juste de ne pas utiliser le Cache de ton Proxy. Ca dépend de ce que tu fais derrière. Dans le doute, je pense que c'est pas plus mal de le mettre, au moins tu iras toujours chercher ta page Web.


    Pour ton erreur.
    En effet, il semblerait que ton authentification Proxy ne se passe pas comme elle devrait.
    Il faut s'assurer que la configuration côté Proxy est bien faite en effet.
    Si tu utilises les DefaultCredentials, il faut s'assurer que ton Proxy a bien les moyens de vérifier que ton compte Windows est bien autorisé à s'authentifier, et que le compte fourni en Credential est lui-même bien autorisé à se connecter au Proxy.

    Ce qui est bizarre, c'es qu'il te met erreur 407, comme si tu n'essayais même pas de te connecter à ton Proxy.

    Essaie de faire un projet à côté, où sans aller chercher toutes tes infos avec ton objet INI, tu fais plusieurs tests en passant les paramètres en dur.
    D'abord avec les DefaultCredentials, ensuite sinon avec des NetworkCredential.
    Dans la MSDN tu as un exemple : http://msdn.microsoft.com/en-us/library/system.net.webrequest.proxy(VS.71).aspx

    En espérant que cela t'aide,

    Thomas

    Thomas Aimonetti - C# - Sharplog Engineering - http://www.sharplog.fr
    mercredi 20 janvier 2010 16:53
  • Bonjour Cyrille,

    Oui, là tu y es, normalement c'est la fin de tes problèmes avec ton proxy :)

    Concernant la vérification de l'URL.
    La fonction IsWellFormedUriString permet de vérifier si une URI est bien formée.
    Une URI bien formée suit 2 RFC, la 2396 : http://www.faqs.org/rfcs/rfc2396.html et la 2372 : http://www.faqs.org/rfcs/rfc2732.html (pour les IP V6)

    En fait, dans un permier temps, les URL sont un sous-ensemble des URI, donc certaines URI ne sont pas des URL.
    Ensuite, dans un deuxième temps, parmi les URL, certaines ne t'intéresseront pas.
    Si on prend par exemple ftp://monIP/monRepertoire, c'est une URL valide, mais c'est du FTP, on a aussi toutes les URLs en IP V6, etc...

    Alors je dois t'avouer que je suis un peu "old school" à ce niveau-là, mais quand je veux une URL HTTP, je fais la vérif à la main.
    Surtout que dans le genre de cas où j'en ai besoin, souvent le proxy est dans l'intranet, donc je limite aussi les URLs permises à cet intranet autant que faire ce peut.

    Voilà pour l'explication :)

    Cordialement,

    Thomas
    Thomas Aimonetti - C# - Sharplog Engineering - http://www.sharplog.fr
    mercredi 27 janvier 2010 09:43

Toutes les réponses

  • Bonsoir,
    Ma question serait-elle idiote ou, au contraire, personne n'aurait-il la réponse ?
    Merci pour votre aide
    Cordialement
    lundi 18 janvier 2010 19:51
  • Bonsoir,

    Je pense que si personne n'a encore répondu, c'est peut-être parce que ton code est mis en vrac, tout simplement.
    Un peu de formatage n'aurait pas été de trop.
    Ensuite, on n'a pas l'erreur que tu obtiens quand tu executes ton code, ni même ce qui se passe, on sait juste que tu n'y arrives pas.

    Bon voyons voir.
    Tu dois te connecter en NTLM à ton Proxy avec un premier lot de Credential, et après fournir un 2eme lot de Credential pour ta page finale.
    Ca doit ressembler à ça :

    Dim proxy As New WebProxy("http://proxy:80/", True)
    
    ' Un des deux au choix suivant comment tu te logges sur ton proxy
    proxy.Credentials = New NetworkCredential("userId", "password", "Domain")
    proxy.Credentials = CredentialCache.DefaultCredentials
    
    hwebrequest.Proxy = proxy
    
    'Un des deux au choix
    hwebrequest.Credentials = CredentialCache.DefaultCredentials
    hwebrequest.Credentials = New System.Net.NetworkCredential(username, password)


    En général, ce genre de config est pour permettre de passer un firewall.
    Donc tu es en CredentialCache.DefaultCredentials pour le proxy, en gros ton account Windows, et en NetworkCredential pour la suite.

    Si cela ne fonctionne pas, essaie de voir laquelle des 2 connexions, celle au proxy ou celle à la page, ne fonctionne pas.

    Cordialement,

    Thomas

    Thomas Aimonetti - C# - Sharplog Engineering - http://www.sharplog.fr
    lundi 18 janvier 2010 20:40
  • Bonsoir,
    Navré pour mon message initial quelque peu brouillon.

    Merci pour votre réponse. J'ai mis à jour mon code en conséquence. Le proxy étant celui d'un utilisateur, je vais lui envoyer la nouvelle version de mon logiciel en espérant que cela fonctionnera. La tâche de débogage n'est donc pas facile, puisque je dois me contenter des fichiers logs faits maison pour obtenir des informations sur l'erreur.

    J'aurais une dernière question. Sur des forums, j'ai lu qu'il fallait mettre les lignes suivantes :

    hwebrequest.KeepAlive = True
    hwebrequest.PreAuthenticate = True
    hwebrequest.Headers.Set("Pragma", "no-cache")

    Ces lignes ci-dessus sont-elles bien utiles ?

    Pour information, l'erreur retournée jusqu'à présent était celle-ci :

    Error type: System.Net.WebException
    Error message: Le serveur distant a retourné une erreur : (407) Authentification proxy requise.
    StackTrace:    à System.Net.HttpWebRequest.GetResponse()

    Il s'agit donc apparemment d'un problème côté Proxy. Peut-il s'agir aussi d'un problème non pas lié à mon code, mais à la configuration du proxy ?

    Encore merci pour votre aide précieuse

    Cordialement,
    Cyrille
    mardi 19 janvier 2010 20:03
  • Bonjour,

    KeepAlive te permet davoir une connexion persistante, à toi de voir si tu en as besoin.

    Pour PreAuthenticate : http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.preauthenticate.aspx
    Vu ton cas, je te conseillerai de le laisser, cela évite les aller-retour inutiles entre le proxy et toi.

    Quant au header no-cache, il te permet juste de ne pas utiliser le Cache de ton Proxy. Ca dépend de ce que tu fais derrière. Dans le doute, je pense que c'est pas plus mal de le mettre, au moins tu iras toujours chercher ta page Web.


    Pour ton erreur.
    En effet, il semblerait que ton authentification Proxy ne se passe pas comme elle devrait.
    Il faut s'assurer que la configuration côté Proxy est bien faite en effet.
    Si tu utilises les DefaultCredentials, il faut s'assurer que ton Proxy a bien les moyens de vérifier que ton compte Windows est bien autorisé à s'authentifier, et que le compte fourni en Credential est lui-même bien autorisé à se connecter au Proxy.

    Ce qui est bizarre, c'es qu'il te met erreur 407, comme si tu n'essayais même pas de te connecter à ton Proxy.

    Essaie de faire un projet à côté, où sans aller chercher toutes tes infos avec ton objet INI, tu fais plusieurs tests en passant les paramètres en dur.
    D'abord avec les DefaultCredentials, ensuite sinon avec des NetworkCredential.
    Dans la MSDN tu as un exemple : http://msdn.microsoft.com/en-us/library/system.net.webrequest.proxy(VS.71).aspx

    En espérant que cela t'aide,

    Thomas

    Thomas Aimonetti - C# - Sharplog Engineering - http://www.sharplog.fr
    mercredi 20 janvier 2010 16:53
  • Bonsoir,
    Encore merci pour vos conseils.

    Concernant l'erreur liée au proxy, en fait, après avoir ajouté des informations supplémentaires dans les logs, j'ai pu constater que la personne ne cochait pas l'option "Utiliser un proxy" dans mon logiciel. Grrrr. Il va refaire les tests en cochant la case.

    Par contre, il me dit qu'il souhaiterait que le logiciel récupère les informations du proxy définies dans IE.

    Est-ce qui suit est correct ?

    Si dans les options de mon application, le proxy est réglé sur "détection automatique", je ne demande aucun info manuelle (ni adresse, ni port, ni login, ni pass) et j'utilise le code suivant :

    Dim proxy As System.Net.WebProxy()
    proxy = WebRequest.DefaultWebProxy
    proxy.Credentials = CredentialCache.DefaultCredentials

    Si dans les options de mon application, le proxy est réglé en manuel, je dois utiliser le code suivant :

    Dim proxy As New System.Net.WebProxy(New Uri(proxyAddress) & ":" & Integer.Parse(proxyPort)), True, noProxyForArray)
    
    proxy.Credentials = New System.Net.NetworkCredential(proxyUsername, proxyPassword")

    Ai-je bon ?
    Encore merci pour votre aide qui me permet d'avoir un code beaucoup plus "propre" :-)
    Cordialement,
    Cyrille
    lundi 25 janvier 2010 19:04
  • Bonjour Cyrille,

    Pour récupérer les paramètres de proxy définis dans IE, c'est très simple et c'est déjà ce que tu fais ici en effet :

    proxy = WebRequest.DefaultWebProxy
    proxy.Credentials = CredentialCache.DefaultCredentials

    Lorsque tu prends le DefaultWebProxy, le framework utilise les mêmes informations que celles qui ont été configurées dans IE.
    Et il te faut en effet rajouter les DefaultCredentials, donc tu as tout bon.

    Concernant la 2ème partie, la configuration du proxy en mode manuel.
    Tu utilises le constructeur avec le bypass en local et avec l'array de sites qui bypassent le proxy : http://msdn.microsoft.com/en-us/library/ms144293.aspx
    Si tu n'as besoin de bypasser ni en local, ni certains sites, tu peux utiliser un constructeur plus simple.
    Cela dépend de tes besoins : http://msdn.microsoft.com/en-us/library/system.net.webproxy.webproxy.aspx

    Sinon, tu as tout bon.
    Si tu veux faire un peu plus, je te conseillerais de vérifier à l'aide d'une expression régulière ton Url fournie manuellement pour ton proxy.
    En voilà un exemple : http://www.osix.net/modules/article/?id=586
    Tu crées une String à partir de proxyAddress + ":" + proxyPort, et tu la testes.
    Si elle est bonne, tu crées l'Uri et tu affectes, si elle est mauvaise, tu envoies un message d'erreur à ton utilisateur.
    Par contre, la Regex que je t'ai envoyée n'est pas complète.
    Elle est plutôt basique mais fonctionnera pour 99,99% des cas.
    Le meilleur moyen de voir si elle marche, c'est la tester :)

    J'avais fait des recherches pour trouver une Regex qui marche vraiment pour toutes les URLs, et j'avais trouvé cela, mais elle est incompréhensible, et il est difficile de savoir si elle fait réellement le boulot : http://internet.ls-la.net/folklore/url-regexpr.html

    Cordialement,

    Thomas

    Thomas Aimonetti - C# - Sharplog Engineering - http://www.sharplog.fr
    mardi 26 janvier 2010 12:43
  • Bonsoir Thomas,

    Ton message est encourageant car je vois que finalement, je m'approche du code que je souhaite obtenir :-)

    Concernant l'adresse du proxy, en fait j'ai deux champs : l'adresse et le port.
    Pour le port, je vérifie qu'il s'agit d'un entier. Pour l'adresse, j'utilise la fonction suivante :

    Uri.IsWellFormedUriString(proxyAddress.Text, UriKind.Absolute)

    Cette vérification n'est pas aussi efficace que la Regex que tu proposes ?

    Encore merci pour toute ton aide.

    Cordialement,
    Cyrille
    mardi 26 janvier 2010 21:01
  • Bonjour Cyrille,

    Oui, là tu y es, normalement c'est la fin de tes problèmes avec ton proxy :)

    Concernant la vérification de l'URL.
    La fonction IsWellFormedUriString permet de vérifier si une URI est bien formée.
    Une URI bien formée suit 2 RFC, la 2396 : http://www.faqs.org/rfcs/rfc2396.html et la 2372 : http://www.faqs.org/rfcs/rfc2732.html (pour les IP V6)

    En fait, dans un permier temps, les URL sont un sous-ensemble des URI, donc certaines URI ne sont pas des URL.
    Ensuite, dans un deuxième temps, parmi les URL, certaines ne t'intéresseront pas.
    Si on prend par exemple ftp://monIP/monRepertoire, c'est une URL valide, mais c'est du FTP, on a aussi toutes les URLs en IP V6, etc...

    Alors je dois t'avouer que je suis un peu "old school" à ce niveau-là, mais quand je veux une URL HTTP, je fais la vérif à la main.
    Surtout que dans le genre de cas où j'en ai besoin, souvent le proxy est dans l'intranet, donc je limite aussi les URLs permises à cet intranet autant que faire ce peut.

    Voilà pour l'explication :)

    Cordialement,

    Thomas
    Thomas Aimonetti - C# - Sharplog Engineering - http://www.sharplog.fr
    mercredi 27 janvier 2010 09:43
  • Bonjour Thomas,

    Merci pour tes conseils. Je crois que je vais continuer à les suivre en ce qui concerne l'URL ;-)

    Cordialement,
    Cyrille
    mercredi 27 janvier 2010 19:59
  • Bonjour Cyrille,

    Ok, tiens-moi au courant des évolutions et si tout s'est bien passé :)

    Cordialement,

    Thomas
    Thomas Aimonetti - C# - Sharplog Engineering - http://www.sharplog.fr
    vendredi 29 janvier 2010 11:16
  • Bonsoir Thomas,

    Aucun problème. Lorsque la beta sera lancée, je te tiendrai au courant du résultat.

    Cordialement,
    Cyrille
    vendredi 29 janvier 2010 20:52
  • Bonsoir Thomas,

    Voila, la beta s'est bien déroulée. La version finale vient d'être publiée. Il semblerait que tout fonctionne bien pour les options du proxy. Encore merci !

    Cyrille

    mercredi 14 avril 2010 18:54