Accès à HttpListener refusé

J’écris un serveur HTTP en C #.

Lorsque j’essaie d’exécuter la fonction HttpListener.Start() je reçois une HttpListenerException

“Accès refusé”.

Lorsque je lance l’application en mode admin dans Windows 7, cela fonctionne bien.

Puis-je le faire fonctionner sans mode administrateur? si oui comment? Si non, comment puis-je faire en sorte que l’application passe en mode admin après avoir démarré?

 using System; using System.Net; namespace ConsoleApplication1 { class Program { private HttpListener httpListener = null; static void Main(ssortingng[] args) { Program p = new Program(); p.Server(); } public void Server() { this.httpListener = new HttpListener(); if (httpListener.IsListening) throw new InvalidOperationException("Server is currently running."); httpListener.Prefixes.Clear(); httpListener.Prefixes.Add("http://*:4444/"); try { httpListener.Start(); //Throws Exception } catch (HttpListenerException ex) { if (ex.Message.Contains("Access is denied")) { return; } else { throw; } } } } } 

Oui, vous pouvez exécuter HttpListener en mode non-admin. Tout ce que vous devez faire est d’accorder des permissions à l’URL particulière. par exemple

 netsh http add urlacl url=http://+:80/MyUri user=DOMAIN\user 

La documentation est ici

Puis-je le faire fonctionner sans mode administrateur? si oui comment? Si non, comment puis-je faire en sorte que l’application passe en mode admin après avoir démarré?

Vous ne pouvez pas, il doit commencer avec des privilèges élevés. Vous pouvez le redémarrer avec le verbe runas , qui runas l’utilisateur à passer en mode admin

 static void RestartAsAdmin() { var startInfo = new ProcessStartInfo("yourApp.exe") { Verb = "runas" }; Process.Start(startInfo); Environment.Exit(0); } 

EDIT: en fait, ce n’est pas vrai; HttpListener peut s’exécuter sans privilèges élevés, mais vous devez autoriser l’URL sur laquelle vous souhaitez écouter. Voir la réponse de Darrel Miller pour plus de détails.

Si vous utilisez http://localhost:80/ comme préfixe, vous pouvez écouter les requêtes http sans avoir besoin de privilèges administratifs.

La syntaxe était incorrecte pour moi, vous devez inclure les guillemets:

 netsh http add urlacl url="http://+:4200/" user=everyone 

sinon j’ai reçu “le paramètre est incorrect”

Si vous souhaitez utiliser l’indicateur “user = Everyone”, vous devez l’ajuster à la langue de votre système. En anglais c’est comme mentionné:

 netsh http add urlacl url=http://+:80/ user=Everyone 

En allemand ce serait:

 netsh http add urlacl url=http://+:80/ user=Jeder 

En tant qu’alternative ne nécessitant ni élévation ni netsh, vous pouvez également utiliser TcpListener par exemple.

Ce qui suit est un extrait modifié de cet exemple: https://github.com/googlesamples/oauth-apps-for-windows/tree/master/OAuthDesktopApp

 // Generates state and PKCE values. ssortingng state = randomDataBase64url(32); ssortingng code_verifier = randomDataBase64url(32); ssortingng code_challenge = base64urlencodeNoPadding(sha256(code_verifier)); const ssortingng code_challenge_method = "S256"; // Creates a redirect URI using an available port on the loopback address. var listener = new TcpListener(IPAddress.Loopback, 0); listener.Start(); ssortingng redirectURI = ssortingng.Format("http://{0}:{1}/", IPAddress.Loopback, ((IPEndPoint)listener.LocalEndpoint).Port); output("redirect URI: " + redirectURI); // Creates the OAuth 2.0 authorization request. ssortingng authorizationRequest = ssortingng.Format("{0}?response_type=code&scope=openid%20profile&redirect_uri={1}&client_id={2}&state={3}&code_challenge={4}&code_challenge_method={5}", authorizationEndpoint, System.Uri.EscapeDataSsortingng(redirectURI), clientID, state, code_challenge, code_challenge_method); // Opens request in the browser. System.Diagnostics.Process.Start(authorizationRequest); // Waits for the OAuth authorization response. var client = await listener.AcceptTcpClientAsync(); // Read response. var response = ReadSsortingng(client); // Brings this app back to the foreground. this.Activate(); // Sends an HTTP response to the browser. WriteSsortingngAsync(client, "Please close this window and return to the app.").ContinueWith(t => { client.Dispose(); listener.Stop(); Console.WriteLine("HTTP server stopped."); }); // TODO: Check the response here to get the authorization code and verify the code challenge 

Les méthodes de lecture et d’écriture étant:

 private ssortingng ReadSsortingng(TcpClient client) { var readBuffer = new byte[client.ReceiveBufferSize]; ssortingng fullServerReply = null; using (var inStream = new MemoryStream()) { var stream = client.GetStream(); while (stream.DataAvailable) { var numberOfBytesRead = stream.Read(readBuffer, 0, readBuffer.Length); if (numberOfBytesRead <= 0) break; inStream.Write(readBuffer, 0, numberOfBytesRead); } fullServerReply = Encoding.UTF8.GetString(inStream.ToArray()); } return fullServerReply; } private Task WriteStringAsync(TcpClient client, string str) { return Task.Run(() => { using (var writer = new StreamWriter(client.GetStream(), new UTF8Encoding(false))) { writer.Write("HTTP/1.0 200 OK"); writer.Write(Environment.NewLine); writer.Write("Content-Type: text/html; charset=UTF-8"); writer.Write(Environment.NewLine); writer.Write("Content-Length: " + str.Length); writer.Write(Environment.NewLine); writer.Write(Environment.NewLine); writer.Write(str); } }); } 

Vous pouvez démarrer votre application en tant qu’administrateur si vous ajoutez un manifeste d’application à votre projet.

Ajoutez simplement un nouvel élément à votre projet et sélectionnez “Fichier manifeste de l’application”. Modifiez l’élément pour:

  

Par défaut, Windows définit le préfixe suivant accessible à tous: http: // +: 80 / Temporary_Listen_Addresses /

Vous pouvez donc enregistrer votre HttpListener via:

Prefixes.Add("http://+:80/Temporary_Listen_Addresses/" + Guid.NewGuid().ToSsortingng("D") + "/";

Cela provoque parfois des problèmes avec des logiciels tels que Skype qui essaieront d’utiliser le port 80 par défaut.

 httpListener.Prefixes.Add("http://*:4444/"); 

vous utilisez “*” donc vous exécutez cmd suivant comme administrateur

 netsh http add urlacl url=http://*:4444/ user=username 

no use +, doit utiliser *, car vous spécifiez *: 4444 ~.

https://msdn.microsoft.com/fr-fr/library/system.net.httplistener.aspx

J’ai également fait face à un problème similaire.Si vous avez déjà réservé url, vous devez d’abord supprimer l’URL pour s’exécuter en mode non admin sinon il échouera avec Access est refusé erreur.

 netsh http delete urlacl url=http://+:80