Accès À HttpListener Refusé

j'écris un serveur HTTP en C#.

quand j'essaie d'exécuter la fonction HttpListener.Start() j'obtiens un HttpListenerException disant

"Accès Refusé".

quand j'exécute l'application en mode administrateur dans windows 7 Il fonctionne très bien.

puis-je le faire fonctionner sans mode administrateur? si oui, comment? Si ce n'est pas le cas, comment puis-je faire changer l'application en mode administrateur après avoir démarré l'application?

using System;
using System.Net;

namespace ConsoleApplication1
{
    class Program
    {
        private HttpListener httpListener = null;

        static void Main(string[] 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;
                }
            }
        }
    }
}
132
demandé sur John Saunders 2010-10-26 02:44:16

10 réponses

Oui vous pouvez exécuter HttpListener en mode non-administrateur. 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

Documentation est ici .

251
répondu Darrel Miller 2010-11-06 21:44:59

puis-je le faire fonctionner sans mode administrateur? si oui, comment? Si ce n'est pas le cas, comment puis-je faire changer l'application en mode administrateur après avoir démarré l'application?

vous ne pouvez pas, il faut commencer avec des privilèges élevés. Vous pouvez le redémarrer avec le verbe runas , qui invite l'utilisateur à passer en mode administrateur

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 courir sans privilèges élevés, mais vous devez donner la permission pour L'URL sur laquelle vous voulez écouter. Voir réponse de Darrel Miller pour plus de détails.

27
répondu Thomas Levesque 2017-05-23 10:31:37

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

16
répondu Ehsan Mirsaeedi 2013-09-13 12:35:29

la syntaxe était fausse pour moi, vous devez inclure les citations:

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

sinon j'ai reçu "le paramètre est incorrect "

13
répondu Dave 2015-05-06 11:45:29

dans le cas où vous voulez utiliser le drapeau" user=Everyone " vous devez l'ajuster à votre langage système. En anglais, il est comme il est mentionné:

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

en allemand ce serait:

netsh http add urlacl url=http://+:80/ user=Jeder
8
répondu Christoph Brückmann 2016-08-04 13:48:05

comme alternative qui ne nécessite pas d'élévation ou netsh, vous pouvez également utiliser TcpListener par exemple.

l'extrait suivant est un extrait modifié de cet échantillon.: https://github.com/googlesamples/oauth-apps-for-windows/tree/master/OAuthDesktopApp

// Generates state and PKCE values.
string state = randomDataBase64url(32);
string code_verifier = randomDataBase64url(32);
string code_challenge = base64urlencodeNoPadding(sha256(code_verifier));
const string 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();
string redirectURI = string.Format("http://{0}:{1}/", IPAddress.Loopback, ((IPEndPoint)listener.LocalEndpoint).Port);
output("redirect URI: " + redirectURI);

// Creates the OAuth 2.0 authorization request.
string authorizationRequest = string.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.EscapeDataString(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 = ReadString(client);

// Brings this app back to the foreground.
this.Activate();

// Sends an HTTP response to the browser.
WriteStringAsync(client, "<html><head><meta http-equiv='refresh' content='10;url=https://google.com'></head><body>Please close this window and return to the app.</body></html>").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 string ReadString(TcpClient client)
{
    var readBuffer = new byte[client.ReceiveBufferSize];
    string 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);
        }
    });
}
7
répondu Michael Olsen 2017-10-03 13:44:38

vous pouvez démarrer votre application en tant qu'administrateur si vous ajoutez le Manifeste D'Application à votre projet.

il suffit d'Ajouter un nouvel élément à votre projet et sélectionnez"application Manifest File". Remplacer l'élément <requestedExecutionLevel> par:

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
5
répondu R.Titov 2016-02-25 16:54:07

Par Défaut Windows définit le préfixe suivant qui est disponible pour tout le monde: http://+: 80 / Temporary_Listen_Addresses/

pour que vous puissiez enregistrer votre HttpListener via:

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

cela cause parfois des problèmes avec des logiciels tels que Skype qui vont essayer d'utiliser le port 80 par défaut.

5
répondu Sebastian 2017-03-08 09:24:27
httpListener.Prefixes.Add("http://*:4444/");

vous utilisez " * "alors vous exécutez cmd suivant comme administrateur

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

pas d'utilisation +, doit utiliser *, parce que vous spec *:4444~.

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

1
répondu NamedStar 2017-08-15 14:27:13

j'ai également fait face à un problème similaire.Si vous avez déjà réservé url alors vous devez d'abord supprimer l'url à exécuter en mode non administrateur sinon il échouera avec L'accès est refusé erreur.

netsh http delete urlacl url=http://+:80
0
répondu vivek nuna 2016-10-19 09:29:32