skoruba / IdentityServer4.Admin

The administration for the IdentityServer4 and Asp.Net Core Identity
MIT License
3.57k stars 1.15k forks source link

Using HTTP.sys and running as windows service #469

Open ChristianRiedl opened 4 years ago

ChristianRiedl commented 4 years ago

I would like to run your 3 web apps using HTTP.sys and as windows service sharing the standard http and https ports.

Using your latest ASPnet core 3.1 version it was easy to make some modifications in program.cs and now it runs on

It only requires to add two packages :

Of course it would be great to integrate it in your solution, but I have no idea how in can be done in a way that it is easy to create the 2 different versions.

Maybe using #if HTTPsys in program.cs and different .csproj files ?

skoruba commented 4 years ago

Hi, why do you prefer windows service?

ChristianRiedl commented 4 years ago

In my opinion it is the standard way to run services (= background tasks, = demons) on a Windows Server. It is only a server for my private use (smart home, media). I use OpenId Connect auth only to combine hobby with learning :-). All my AspNetCore sites are running as Windows Service. I think I am not the only man on world running windows services.

But the main thing is that I like the port sharing with HTTP.sys

skoruba commented 4 years ago

I see, I will check some details about http.sys in general, I have never used this before.

ChristianRiedl commented 4 years ago

Fine. I show you the provisional changes I made in Program.cs. GetCurrentDirectory is not possible in a windows service.

using System;
using System.IO;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Serilog;
#if HTTPSYS
using Microsoft.AspNetCore.Server.HttpSys;
#endif

namespace Identity.STS.Identity
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Log.Logger = new LoggerConfiguration()
                .ReadFrom.Configuration(Configuration)
                .CreateLogger();
            try
            {
                CreateHostBuilder(args).Build().Run();
            }
            catch (Exception ex)
            {
                Log.Fatal(ex, "Host terminated unexpectedly");
            }
            finally
            {
                Log.CloseAndFlush();
            }
        }
        private static string GetBaseDirectory ()
        {
#if HTTPSYS
            // Current Directory is not set
            var directory = AppContext.BaseDirectory;
            while (!string.IsNullOrEmpty(directory))
            {
                string rootPath = Path.Combine(directory, "wwwroot");
                if (Directory.Exists(rootPath))
                {
                     return directory;
                }
                directory = Path.GetDirectoryName(directory);
            }
#endif
            return Directory.GetCurrentDirectory();
        }
        public static IConfiguration Configuration { get; } = new ConfigurationBuilder()
            .SetBasePath(GetBaseDirectory())
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile("serilog.json", optional: true, reloadOnChange: true)
            .AddEnvironmentVariables()
            .Build();

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
#if HTTPSYS 
                 .UseWindowsService()
#endif            
                 .ConfigureAppConfiguration((hostContext, configApp) =>
                 {
                     configApp.AddJsonFile("serilog.json", optional: true, reloadOnChange: true);

                     if (hostContext.HostingEnvironment.IsDevelopment())
                     {
                         configApp.AddUserSecrets<Startup>();
                     }

                     configApp.AddEnvironmentVariables();
                     configApp.AddCommandLine(args);
                 })
                .ConfigureWebHostDefaults(webBuilder =>
                {
#if HTTPSYS
                    webBuilder.UseContentRoot(GetBaseDirectory());
                    webBuilder.UseHttpSys(options =>
                    {
                        options.AllowSynchronousIO = true;
                        options.Authentication.Schemes = AuthenticationSchemes.None;
                        options.Authentication.AllowAnonymous = true;
                        options.MaxConnections = null;
                        options.MaxRequestBodySize = 30000000;
                        options.UrlPrefixes.Add("http://192.168.1.100/Identity");
                        options.UrlPrefixes.Add("https://192.168.1.100/Identity");
                    });
#else
                    webBuilder.ConfigureKestrel(options => options.AddServerHeader = false);
#endif
                    webBuilder.UseStartup<Startup>();
                })
                .UseSerilog((hostContext, loggerConfig) =>
                {
                    loggerConfig
                        .ReadFrom.Configuration(hostContext.Configuration)
                        .Enrich.WithProperty("ApplicationName", hostContext.HostingEnvironment.ApplicationName);
                });
    }
}
danielmeza commented 4 years ago

This look like another template for the host, we can separate all the web stuff from the host project and have several host environments to avoid use compiler variables. Or perhaps just making serveral programs files template an selectin in the dotnet new command

ChristianRiedl commented 4 years ago

I don't think compiler variables are bad in every case. As far as HTTP.sys and Windows service is concerned, I suggest waiting to see if other people would like that too. The effort is not worth it for me alone. Maybe you mark the issue with "feature request". Is there a possibility in github to "vote" for features ?