私はasp.netコアWebAPI2.1アプリを開発しています。
静的クラスの拡張メソッドとしてJWT認証サービスを追加します。
public static class AuthenticationMiddleware
{
public static IServiceCollection AddJwtAuthentication(this IServiceCollection services, string issuer, string key)
{
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
// validate the server that created that token
ValidateIssuer = true,
// ensure that the recipient of the token is authorized to receive it
ValidateAudience = true,
// check that the token is not expired and that the signing key of the issuer is valid
ValidateLifetime = true,
// verify that the key used to sign the incoming token is part of a list of trusted keys
ValidateIssuerSigningKey = true,
ValidIssuer = issuer,
ValidAudience = issuer,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key))
};
});
return services;
}
}
これは、StartupクラスのConfigureServicesメソッドで次のように使用します。
public void ConfigureServices(IServiceCollection services)
{
// adding some services here
services.AddJwtAuthentication(Configuration["Jwt:Issuer"], Configuration["Jwt:Key"]);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
ここで、appsettings.jsonからJWT認証データを取得するためにIOptionsパターンを使用する必要があります
ConfigureServicesメソッドでIOptionsを取得して、発行者とキーを拡張メソッドに渡すにはどうすればよいですか?または、IOptionsを拡張メソッドに渡す方法は?
appsettings.json
からModel
にデータをバインドするには、次の手順に従います。
Appsettings.jsonコンテンツ
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Warning"
}
},
"JWT": {
"Issuer": "I",
"Key": "K"
}
}
JWTオプション
public class JwtOptions
{
public string Issuer { get; set; }
public string Key { get; set; }
}
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.Configure<JwtOptions>(Configuration.GetSection("JWT"));
var serviceProvider = services.BuildServiceProvider();
var opt = serviceProvider.GetRequiredService<IOptions<JwtOptions>>().Value;
services.AddJwtAuthentication(opt.Issuer, opt.Key);
services.AddMvc();
}
JwtOptions
を直接渡すもう1つのオプション。
public void ConfigureServices(IServiceCollection services)
{
services.Configure<JwtOptions>(Configuration.GetSection("JWT"));
var serviceProvider = services.BuildServiceProvider();
var opt = serviceProvider.GetRequiredService<IOptions<JwtOptions>>().Value;
services.AddJwtAuthentication(opt);
services.AddMvc();
}
拡張方法を変更します。
public static IServiceCollection AddJwtAuthentication(this IServiceCollection services, JwtOptions opt)
もう1つのオプションは、構成をBind()
拡張子を持つクラスにバインドすることです。 (IMOこれはIOptionsよりもクリーンなソリューションです)
public class JwtKeys
{
public string Issuer { get; set; }
public string Key { get; set; }
}
public void ConfigureServices(IServiceCollection services)
{
var jwtKeys = new JwtKeys();
Configuration.GetSection("JWT").Bind(JwtKeys);
services.AddJwtAuthentication(jwtKeys);
}
public static IServiceCollection AddJwtAuthentication(this IServiceCollection services, JwtKeys jwtKeys)
{....}
次に、ソリューションの他の場所でJwtKeys設定が必要な場合は、コレクションにクラスを登録し、必要な場所に挿入するだけです。
services.AddSingleton(jwtKeys);
次のように、StartupクラスのDIコンテナにオプションを追加できます。
public class JwtOptions
{
public string Issuer { get; set; }
public string Key { get; set; }
}
public void ConfigureService(IServiceCollection services)
{
services.AddOptions();
services.Configure<JwtOptions>(Configuration.GetSection("Jwt"));
}
これで、構成段階、または拡張メソッドでこのオプションを使用できます。
public void Configure(IApplicationBuilder app)
{
var options = app.ApplicationServices.GetService<IOptions<JwtOptions>();
// write your own code
}