Httplistener -Zugang verweigert
-
26-09-2019 - |
Frage
Ich schreibe einen HTTP -Server in C#.
Wenn ich versuche, die Funktion auszuführen HttpListener.Start()
Ich bekomme eine HttpListenerException
Sprichwort
"Zugriff abgelehnt".
Wenn ich die App im Administratormodus in Windows 7 ausführe, funktioniert sie gut.
Kann ich es ohne Administratormodus laufen lassen? Wenn ja, wie? Wenn nicht, wie kann ich nach dem Ausführen die App in den Administratormodus ändern?
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;
}
}
}
}
}
Lösung
Ja, Sie können httplistener im Nicht-Adminampfer-Modus ausführen. Alles, was Sie tun müssen, ist, der jeweiligen URL Berechtigungen zu gewähren. z.B
netsh http add urlacl url=http://+:80/MyUri user=DOMAIN\user
Dokumentation ist hier.
Andere Tipps
Kann ich es ohne Administratormodus laufen lassen? Wenn ja, wie? Wenn nicht, wie kann ich nach dem Ausführen die App in den Administratormodus ändern?
Sie können nicht, es muss mit erhöhten Privilegien beginnen. Sie können es mit dem neu starten runas
Verb, das den Benutzer auffordert, in den Administratormodus zu wechseln
static void RestartAsAdmin()
{
var startInfo = new ProcessStartInfo("yourApp.exe") { Verb = "runas" };
Process.Start(startInfo);
Environment.Exit(0);
}
Bearbeiten: Eigentlich ist das nicht wahr; Httplistener kann ohne erhöhte Privilegien laufen, aber Sie müssen die Erlaubnis für die URL geben, auf die Sie zuhören möchten. Sehen Darrel Millers Antwort für Details.
Wenn du benutzt http://localhost:80/
Als Präfix können Sie HTTP -Anfragen ohne Verwaltungsrechte anhören.
Die Syntax war falsch für mich, Sie müssen die Zitate einschließen:
netsh http add urlacl url="http://+:4200/" user=everyone
Andernfalls habe ich "Der Parameter ist falsch" erhalten. "
Falls Sie das Flag "user = jeder" verwenden möchten, müssen Sie es an Ihre Systemsprache anpassen. Auf Englisch ist es wie erwähnt:
netsh http add urlacl url=http://+:80/ user=Everyone
Auf Deutsch wäre es:
netsh http add urlacl url=http://+:80/ user=Jeder
Als Alternative, die keine Höhe oder Netsh erfordert, können Sie beispielsweise auch TCplistener verwenden.
Das Folgende ist ein modifizierter Auszug dieses Beispiels:https://github.com/googlessamples/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
Die Lese- und Schreibmethoden sind:
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);
}
});
}
Sie können Ihre Anwendung als Administrator starten, wenn Sie Ihrem Projekt Bewerbungsinformationen hinzufügen.
Fügen Sie einfach Ihrem Projekt ein neues Element hinzu und wählen Sie "Anwendungsmanifest -Datei". Ändere das <requestedExecutionLevel>
Element zu:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
Standardmäßig definiert Windows das folgende Präfix, das allen verfügbar ist:http: //+: 80/temporary_listen_addresses/
So können Sie Ihre registrieren HttpListener
über:
Prefixes.Add("http://+:80/Temporary_Listen_Addresses/" + Guid.NewGuid().ToString("D") + "/";
Dies führt manchmal zu Problemen mit Software wie Skype, die standardmäßig versuchen, Port 80 zu verwenden.
httpListener.Prefixes.Add("http://*:4444/");
Sie verwenden "*"
netsh http add urlacl url=http://*:4444/ user=username
Keine Verwendung +, muss *verwenden *, weil Sie spec *: 4444 ~.
https://msdn.microsoft.com/en-us/library/system.net.httplistener.aspx
Ich habe auch ein ähnliches Problem gestellt. Wenn Sie bereits URL reserviert haben, müssen Sie zuerst die URL löschen, um im Nicht -Administrator -Modus ausgeführt zu werden.
netsh http delete urlacl url=http://+:80
Netsh erfordert die Rechte von Verwaltungsrechten
Sie können dies für Localhost ohne Administratorrechte beheben, indem Sie IgnoreWriteExceptions festlegen:
listener.IgnoreWriteExceptions = True
listener.Start()