appsettings.json
ファイルで定義されたAAD認証情報を持つRazor Pagesを備えたASP.NET Core 2.1 Webアプリケーションがあります(デフォルトのアプリケーションテンプレートのおかげです。その方法については以下を参照してください)。ただし、Startup.cs
で認証を構成しようとすると、構成にはappsettings.json
の構成値が含まれません。デバッガーでIConfiguration
オブジェクトを調べると、環境変数の構成のみがあるように見えます。
問題があるStartup.ConfigureServices
メソッドは次のとおりです。
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options =>
{
// This is from the default template. It should work, but the relevant settings aren't there so options isn't populated.
this.Configuration.Bind("AzureAd", options);
// This of course works fine
options.Instance = "MyInstance";
options.Domain = "MyDomain";
options.TenantId = "MyTenantId";
options.ClientId = "MyClientId";
options.CallbackPath = "MyCallbackPath";
});
services.AddMvc(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
また、重要な場合のサービス構成(これは、サービスファブリックステートレスサービスの上に構築されていることに注意してください):
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new ServiceInstanceListener[]
{
new ServiceInstanceListener(serviceContext =>
new KestrelCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
{
ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting Kestrel on {url}");
return new WebHostBuilder()
.UseKestrel(opt =>
{
int port = serviceContext.CodePackageActivationContext.GetEndpoint("ServiceEndpoint").Port;
opt.Listen(IPAddress.IPv6Any, port, listenOptions =>
{
listenOptions.UseHttps(GetCertificateFromStore());
listenOptions.NoDelay = true;
});
})
.ConfigureServices(
services => services
.AddSingleton<StatelessServiceContext>(serviceContext))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseUrls(url)
.Build();
}))
};
}
このサービスを作成するには、VS2017のウィザードを使用しました。既存のサービスファブリックプロジェクト(.sfproj
)を選択し、Services > Add > New Service Fabric Service
を選択し、Stateless ASP.NET Core [for .NET Framework]
を選択した後、次のページでWeb Application
(MVCではなくRazor Pagesを使用するもの)を選択しました)[Change Authentication
]をクリックし、Work or School Accounts
を選択してAAD情報を入力しました。このテンプレートに加えた唯一の変更は、Startup.ConfigureServices
のAddAzureAD
への呼び出し内にコードを追加し、appsettings.json
ファイルを常に出力ディレクトリにコピーするように設定することです。
appsettings.json
ファイルが構成に読み込まれないのはなぜですか?理解しているように、これはデフォルトで発生するはずですが、何かが欠落しているようです...
WebHostBuilder
は読み込まれませんappsettings.json
デフォルトでは、AddJsonFile
を手動で呼び出す必要があります。例えば:
return new WebHostBuilder()
.UseKestrel(opt =>
{
//snip
})
.ConfigureAppConfiguration((builderContext, config) =>
{
config.AddJsonFile("appsettings.json", optional: false);
})
.ConfigureServices(
services => services
.AddSingleton<StatelessServiceContext>(serviceContext))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseUrls(url)
.Build();
または、 WebHost.CreateDefaultBuilder
より多くのデフォルトをロードします。
別のアプローチは、ConfigurationBuilder
を介して手動で構成を作成し、UseConfiguration
メソッドを使用することです。
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", false, true)
.Build();
var Host = new WebHostBuilder()
.UseConfiguration(configuration)
.UseKestrel()
.UseStartup<Startup>();
主要な目的は、実装時に多少の柔軟性を提供するためのコアであり、多くの場合、エラーが少ないほど多くなります。パイプラインが比較的小さいままであるように、あなたが望むものを明示的に言わなければなりません。