Acceso denegado a HttpListener


Estoy escribiendo un servidor HTTP en C#.

Cuando intento ejecutar la función {[1] } me sale un HttpListenerException diciendo

"Acceso Denegado".

Cuando corro la aplicación en modo admin en Windows 7 funciona bien.

¿Puedo hacer que se ejecute sin el modo admin? en caso afirmativo, ¿cómo? Si no, ¿cómo puedo hacer que la aplicación cambie al modo de administrador después de comenzar a ejecutarse?

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;
                }
            }
        }
    }
}
Author: John Saunders, 2010-10-26

10 answers

Sí puede ejecutar HttpListener en modo no administrador. Todo lo que necesita hacer es otorgar permisos a la URL en particular. por ejemplo,

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

La documentación está aquí .

 251
Author: Darrel Miller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-06 21:44:59

¿Puedo hacer que se ejecute sin el modo admin? en caso afirmativo, ¿cómo? Si no, ¿cómo puedo hacer que la aplicación cambie al modo de administrador después de comenzar a ejecutarse?

No puede, tiene que comenzar con privilegios elevados. Puede reiniciarlo con el verbo runas, que le pedirá al usuario que cambie al modo admin

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

EDIT: en realidad, eso no es cierto; HttpListener puede ejecutarse sin privilegios elevados, pero necesita dar permiso para la URL en la que desea escuchar. Ver Darrel Respuesta de Miller para más detalles.

 27
Author: Thomas Levesque,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:37

Si usa http://localhost:80/ como prefijo, puede escuchar solicitudes http sin necesidad de privilegios Administrativos.

 16
Author: Ehsan Mirsaeedi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-13 12:35:29

La sintaxis era incorrecta para mí, debe incluir las comillas:

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

De lo contrario recibí"El parámetro es incorrecto"

 13
Author: Dave,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-06 11:45:29

En caso de que desee usar la bandera "user=Everyone", debe ajustarla al idioma de su sistema. En inglés es como se menciona:

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

En alemán sería:

netsh http add urlacl url=http://+:80/ user=Jeder
 8
Author: Christoph Brückmann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-04 13:48:05

Como alternativa que no requiere elevation o netsh, también podría usar TcpListener, por ejemplo.

El siguiente es un extracto modificado de esta muestra: 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

Los métodos de lectura y escritura son:

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
Author: Michael Olsen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-03 13:44:38

Puede iniciar su aplicación como administrador si agrega Manifiesto de aplicación a su proyecto.

Simplemente Agregue un nuevo elemento a su proyecto y seleccione "Archivo de Manifiesto de la aplicación". Cambie el elemento <requestedExecutionLevel> a:

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
 5
Author: R.Titov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-25 16:54:07

Por defecto Windows define el siguiente prefijo que está disponible para todos: http://+: 80 / Temporary_Listen_Addresses /

Para que pueda registrar su HttpListener a través de:

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

Esto a veces causa problemas con software como Skype que intentará utilizar el puerto 80 por defecto.

 5
Author: Sebastian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-08 09:24:27
httpListener.Prefixes.Add("http://*:4444/");

Usa " * " para ejecutar el siguiente cmd como administrador

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

No use +, debe usar *, porque especifica*: 4444~.

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

 1
Author: NamedStar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-15 14:27:13

También me enfrenté a un problema similar.Si ya tiene la url reservada, primero debe eliminar la url para ejecutarse en modo no administrativo, de lo contrario fallará con el error de acceso denegado.

netsh http delete urlacl url=http://+:80
 0
Author: vivek nuna,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-19 09:29:32