Search code examples
asp.net-corewindows-servicesblazor-webassembly

Getting Blazor WebAssembly Server running as a Windows Service using https


I created a standard blazor web assembly from VS 2022 from the template. It needs to run in a windows service using https. All source code is located here:

https://github.com/dgxhubbard/BlazorServiceApp

I kept getting errors, about code formatting and the hyperlinks, and after several attempts to re-format the code and links I gave up. CTRL+K nor tick marks etc worked. So I am going to give links to the code and articles instead.

Instructions for adding the code to run as a service came from this article:

https://code-maze.com/aspnetcore-running-applications-as-windows-service/

Then I needed a certificate to use for https. I added code in project GenerateCert to do this and followed this article:

https://www.humankode.com/asp-net-core/develop-locally-with-https-self-signed-certificates-and-asp-net-core/

for asp.net core to use the certificate. I also used this question as a source for the code:

How to create a valid, self-signed X509Certificate2 programmatically, not loading from file in .NET Core

The Blazor Server code:

https://github.com/dgxhubbard/BlazorServiceApp/blob/main/BlazorServiceApp/Server/Program.cs

Code to generate a certificate:

https://github.com/dgxhubbard/BlazorServiceApp/blob/main/GenerateCert/Program.cs

After compiling I ran GenerateCert and copied blzcert.pfx and blzcert.cer to the blazor server bin directory. Then I opened a command prompt and switched to the blazor server bin directory and ran the command to enable the blazor server to run as a service:

sc create api binPath="ServerBinPath\BlazorService.exe"

and then started the service:

sc start api

and the service was running. Then I opened chrome and went to the url for the server https://localhost:7224. And chrome generates a 404. For testing not as a service I had already opened the chrome Advanced and clicked proceed to localhost. So I am not sure why I am getting a 404 when running as a service. Where have I gone wrong here?

Also note I have looked at this question as well but it did not resolve my issue:

ASP.NET Core 3.1 Web API : can it be self-hosted as Windows service with https and use some certificate like IIS?


Solution

  • To use your method, you need to consider the location of the certificate. When creating a Windows service, you may not be able to find the location of the certificate.

    I used the method in this link you provided to test, the service starts normally and I can browse https://localhost:7224.

    Program.cs:

    public class Program
    {
        public static void Main ( string [] args )
        {
            var webApplicationOptions = new WebApplicationOptions()
            {
                Args = args,
                ContentRootPath = AppContext.BaseDirectory,
                ApplicationName = System.Diagnostics.Process.GetCurrentProcess().ProcessName
            };
    
            var builder = WebApplication.CreateBuilder(new WebApplicationOptions
            {
                Args = args,
                ContentRootPath = WindowsServiceHelpers.IsWindowsService() ? AppContext.BaseDirectory : default
            });
    
            builder.Host.UseWindowsService ();
    
            builder.Services.AddWindowsService(options =>
            {
                options.ServiceName = "api";
            });
    
            builder.WebHost.UseKestrel((context,serverOptions) =>
            {
                serverOptions.Configure(context.Configuration.GetSection("Kestrel"))
                .Endpoint("HTTPS", listenOptions =>
                {
                    listenOptions.HttpsOptions.SslProtocols = SslProtocols.Tls12;
                });
            });
    
            // Add services to the container.
    
            builder.Services.AddControllersWithViews ();
            builder.Services.AddRazorPages ();
    
    
            builder.Services.AddMvc(options =>
            {
                options.SslPort = 7224;
                options.Filters.Add(new RequireHttpsAttribute());
            });
    
            builder.Services.AddAntiforgery(
                options =>
                {
                    options.Cookie.Name = "_af";
                    options.Cookie.HttpOnly = true;
                    options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
                    options.HeaderName = "X-XSRF-TOKEN";
                }
            );
    
    
            // NLog: Setup NLog for Dependency injection
            builder.Logging.ClearProviders ();
            builder.Logging.SetMinimumLevel ( Microsoft.Extensions.Logging.LogLevel.Trace );
            builder.Host.UseNLog();
                
    
            var app = builder.Build ();
    
            // Configure the HTTP request pipeline.
            if ( app.Environment.IsDevelopment () )
            {
                app.UseWebAssemblyDebugging ();
            }
            else
            {
                app.UseExceptionHandler ( "/Error" );
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts ();
            }
    
            app.UseHttpsRedirection ();
    
            app.UseBlazorFrameworkFiles ();
            app.UseStaticFiles ();
    
            app.UseRouting ();
    
    
            app.MapRazorPages ();
            app.MapControllers ();
            app.MapFallbackToFile ( "index.html" );
    
            app.Run ();
        }
    }
    

    appsettings.json:

    "Kestrel": {
      "Endpoints": {
        "Http": {
          "Url": "http://localhost:5000"
        },
        "HttpsInlineCertFile": {
          "Url": "https://localhost:7224",
          "Certificate": {
            "Path": "C:\\tmp\\localhost.pfx",
            "Password": "YourSecurePassword"
          }
        }
      }
    

    Then publish your application and create windows service: enter image description here

    Test Result: enter image description here

    Please note make sure your project works fine locally and visit the site.