大人の事情で、ASP.NET Core アプリを Microsoft.AspNetCore.Hosting.WindowsServices を使って Windows サービスでホストしていたんだけど、カレントディレクトリの変更は不要と思ってコードを省略したら、ヒドイ目にあった。
public class Program { public static void Main(string[] args) { var isService = !(Debugger.IsAttached || args.Contains("--console")); // これを忘れたらダメ!ゼッタイ!忘れたらヒドイ目にあう、かも。 if (isService) { var pathToExe = Process.GetCurrentProcess().MainModule.FileName; var pathToContentRoot = Path.GetDirectoryName(pathToExe); Directory.SetCurrentDirectory(pathToContentRoot); } var builder = CreateWebHostBuilder( args.Where(arg => arg != "--console").ToArray()); var host = builder.Build(); if (isService) { host.RunAsService(); } else { host.Run(); } } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .ConfigureLogging((hostingContext, logging) => { logging.AddEventLog(); }) .UseStartup<Startup>(); }
ASP.NET Core Web API を IdentityServer4 で保護しようとしていて、appsettings.json に IdentityServer4 のアドレスを書いていた。カレントディレクトリの変更を忘れたばかりに、Windows サービスとして動かしたときだけ appsettings.json が読み込まれず。
IdentityServer4 のアドレスを Microsoft.AspNetCore.Authentication.JwtBearer の構成時に指定できなかったので、 IdentityServer4 から署名キーを入手することができなかったようで、アクセストークンの検証時に The signature key was not found が返ってきてしまっていた。
気付くまで 2 日かかったよ…。
ちなみに、 .NET 3.1 から Microsoft.Extensions.Hosting.WindowsServices が推奨されていて、そっちを使うと UseWindowsService 内でカレントディレクトリを切り替えてくれる。早く .NET Core 3.1 か、.NET 6 に移行しなければ。