Je veux faire une simple requête HTTP en C #, mais quelque chose ne fonctionne pas et tout ce que j'ai est le code d'état 403 Forbidden
.
Quand j'essaye de faire la même demande dans Postman, tout fonctionne bien. J'ai essayé d'exécuter Fiddler et de voir tous les en-têtes envoyés par Postman. Je les ai tous copiés, mais j'ai toujours eu 403 Forbidden
dans la demande envoyée par code C #.
public static void Main(string[] args) { FlurlHttp.Configure(settings => { settings.HttpClientFactory = new MyClientFactory(); }); var url = "https://example.com" .AppendPathSegments(new[] { "v1", "oauth", "accesstoken" }) .SetQueryParam("grant_type", "client_credentials") .AllowAnyHttpStatus() .WithBasicAuth("username", "password") .WithHeaders(new { User_Agent = "Something/0.4.0 Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-G975F Build/NRD90M)", X_Secret_Header = "secret_encoded_value", accept_encoding = "gzip, deflate", Accept = "*/*" }); HttpResponseMessage msg = url.GetAsync().Result; Console.WriteLine("StatusCodeString: " + msg.StatusCode.ToString()); Console.WriteLine(); Console.WriteLine(msg.Content.ReadAsStringAsync().Result); } class MyClientFactory : DefaultHttpClientFactory { public override HttpMessageHandler CreateMessageHandler() { return new HttpClientHandler { AllowAutoRedirect = false }; } }
Quelqu'un peut-il m'expliquer pourquoi cela ne fonctionne pas? Mêmes en-têtes, même tout.
J'ai remplacé l'URL par "example.com" car je ne veux pas afficher la véritable URL de l'API ici.
Aussi désolé pour tant d'images ... Je ne sais pas comment montrer le problème ici d'une autre manière.
5 Réponses :
La prochaine étape serait de comparer les demandes et les réponses Raw, de votre code C # et de Postman, de les placer côte à côte et de comparer les différences - je vous assure qu'il y en aurait au moins une. :-)
403
est un problème d'autorisation, donc le jeton serait le premier suspect, car la mauvaise structure de votre requête est plus susceptible de générer une erreur 400
"Mauvaise demande".
Dans ce cas particulier, j'ai exécuté votre code dans VS2019 sur ma machine en utilisant Flurl et cela semble fonctionner correctement. Il renvoie un exemple de page HTML:
<!doctype html> <html> <head> <title>Example Domain</title> <meta charset="utf-8" /> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <style type="text/css"> body { background-color: #f0f0f2; margin: 0; padding: 0; font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; } div { width: 600px; margin: 5em auto; padding: 50px; background-color: #fff; border-radius: 1em; } a:link, a:visited { color: #38488f; text-decoration: none; } @media (max-width: 700px) { body { background-color: #fff; } div { width: auto; margin: 0 auto; border-radius: 0; padding: 1em; } } </style> </head> <body> <div> <h1>Example Domain</h1> <p>This domain is established to be used for illustrative examples in documents. You may use this domain in examples without prior coordination or asking for permission.</p> <p><a href="http://www.iana.org/domains/example">More information...</a></p> </div> </body> </html>
J'ai remplacé l'URL réelle par "example.com" car je ne veux pas afficher la véritable API ici
D'accord, donc votre code fonctionne. Maintenant, allez dans l'onglet "Autorisation" du facteur dans l'exemple de travail et vérifiez si le jeton que vous utilisez est le même que celui que vous avez dans votre code VS
Ma suggestion serait de récupérer les chaînes de demande brutes du postman et de l'application C # et d'utiliser quelque chose comme https://text-compare.com/ pour rechercher les différences. On suppose qu'il y a une différence extrêmement mineure comme une barre oblique supplémentaire qui est très difficile à remarquer à l'œil nu.
J'ai comparé les chaînes de requête en utilisant le site que vous avez fourni, mais le résultat dit: "Les deux textes sont identiques"
De Postman, il devrait y avoir un lien sur le côté droit appelé code. Cliquez dessus, puis sélectionnez C # pour obtenir le code généré par Postman. Collez-le et essayez-le.
Je connais cet ancien, mais pour obtenir le même code C # que le facteur envoyé, laissez le facteur générer le code pour, mais vous devez d'abord obtenir RestSharp lib à partir de nuget ou de la console PM, tapez ceci:
Install-Package RestRequest -Version 1.2.0
Pas:
1- Appelez votre api de repos du facteur
2- Appuyez sur le bouton code 3-Une fenêtre pop-up s'ouvrira, puis choisissez la langue que vous voulez, dans votre cas c'est C #
Pour moi, le problème était les paramètres TLS en C #. Essayez d'ajouter cette ligne au début de votre application ou juste avant votre code de requête HTTP:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Ne publiez pas d'images de texte.
Avez-vous essayé d'utiliser
HttpClient
C #? Cela produit-il le même résultat?Y a-t-il une chance que le 403 provienne d'un serveur proxy?
@TobiasTengler Oui, j'ai essayé d'utiliser HttpClient et cela produit le même résultat.
@JohnWu Lorsque j'exécute la requête avec Fiddler, Postman et C # retournent 403. Mais sans Fiddler Postman fonctionne mais C # ne fonctionne pas