Currently working on a PoC of sorts to find out if I can run Owin self-host without admin rights if I do port/url/firewall stuff with admin rights before execution of the app.

For this purpose I have written this register method:

public int FindAndReserveUrl(int startPort, int endPort)
{
    for (int port = startPort; port <= endPort; port++)
    {
        Console.WriteLine($"Checking port {port} availability...");
        if (IsPortAvailable(port))
        {
            Console.WriteLine($"Port {port} is available. Checking URL reservation...");
            string url = $"http://+:{port}/";
            var (output, error, exitCode) = ExecuteCommand("netsh", $"http show urlacl url={url}");

            // Considering a reservation non-existent if the output only contains the generic header
            // and no specific reservation details.
            bool noReservationExists = output.EndsWith("n-----------------", StringComparison.InvariantCultureIgnoreCase);

            if (noReservationExists || exitCode != 0)
            {
                Console.WriteLine($"No existing URL reservation found for {url}. Proceeding to reserve.");
                AddUrlReservation(port, "Everyone");
                return port; // Successfully reserved this port.
            }
            else
            {
                Console.WriteLine($"Existing URL reservation detected for {url}, moving to next port...");
            }
        }
        else
        {
            Console.WriteLine($"Port {port} is in use, moving to next port...");
        }
    }

    Console.WriteLine("Failed to reserve a URL within the specified port range.");
    return -1; // Indicate failure to find and reserve
}

public void AddUrlReservation(int port, string user)
{
    string url = $"http://+:{port}/";
    // Prepare the command to add the URL reservation
    string addCommand = $"http add urlacl url={url} user={user}";

    // Execute the command and capture the output, error, and exit code
    var (output, error, exitCode) = ExecuteCommand("netsh", addCommand);

    // Provide feedback based on the command's execution result
    if (exitCode == 0)
    {
        // Success: Log the successful addition with any output provided
        Console.WriteLine($"Successfully added URL reservation for {url}.");
        if (!string.IsNullOrWhiteSpace(output))
        {
            Console.WriteLine($"Details: {output}");
        }
    }
    else
    {
        // Failure: Log the failure, including both the output and error information
        Console.WriteLine($"Failed to add URL reservation for {url}.");
        if (!string.IsNullOrWhiteSpace(output))
        {
            Console.WriteLine($"Output: {output}");
        }
        if (!string.IsNullOrWhiteSpace(error))
        {
            Console.WriteLine($"Error: {error}");
        }
    }
}

This executes a port registration via “netsh http add urlacl url=http://+:6003/ user=EVERYONE” (also tried with my personal user).
But still, whenever I try to run the app after registration I get the following error:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Net.HttpListenerException: Access is denied
   at System.Net.HttpListener.AddAllPrefixes()
   at System.Net.HttpListener.Start()
   at Microsoft.Owin.Host.HttpListener.OwinHttpListener.Start(HttpListener listener, Func`2 appFunc, IList`1 addresses, IDictionary`2 capabilities, Func`2 loggerFactory)
   at Microsoft.Owin.Host.HttpListener.OwinServerFactory.Create(Func`2 app, IDictionary`2 properties)
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.Owin.Hosting.ServerFactory.ServerFactoryAdapter.Create(IAppBuilder builder)
   at Microsoft.Owin.Hosting.Engine.HostingEngine.Start(StartContext context)
   at Microsoft.Owin.Hosting.Starter.HostingStarter.Start(StartOptions options)
   at OwinNoAdminPoC.Program.Main(String[] args)

When I double check the registrations they’re there and the port being used in the owin self-host is correct too (6003 for everyone, 6004 for my user, tried both).

Reserved URL            : http://+:6003/
        User: Everyone
            Listen: Yes
            Delegate: No
            SDDL: D:(A;;GX;;;WD)

    Reserved URL            : http://+:6004/
        User: [redacted]
            Listen: Yes
            Delegate: No
            SDDL: D:(A;;GX;;;[redacted])

Any clue what else I’m missing or what else I need to do so I can run my application without admin rights?