共享 ASP.NET Core 3.1 启动和控制器中使用的配置对象的最佳方式是什么
What is the best way to share a Configuration object used in ASP.NET Core 3.1 Startup and Controllers
在 ASP.NET Core 3.1 Startup class 和控制器之间共享配置对象的最佳方式是什么?
我看过一些使用 DI 的示例,这似乎是个好主意,但我需要使用 public void ConfigureServices(IServiceCollection services)
中的依赖项。
此外,该对象依赖于一个 Microsoft.Extensions.Configuration.IConfiguration
实例。
The object will be used within Startup.cs
, within the ConfigureServices
itself as well as in Controllers
.
DI 有用吗?还是解决方案是带参数的单例?
这里是需要分享的具体代码:
// openssl rand -hex 16 => 256 bits when read
var jwt_key = Configuration.GetSection("JwtOption:IssuerSigningKey").Value;
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwt_key));
var tokenValidationParameters = new TokenValidationParameters
{
// The signing key must match!
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
// Validate the JWT Issuer (iss) claim
ValidateIssuer = true,
ValidIssuer = "some host name",
// Validate the JWT Audience (aud) claim
ValidateAudience = true,
ValidAudience = "web_intranet",
// Validate the token expiry
ValidateLifetime = true,
// If you want to allow a certain amount of clock drift, set that here:
ClockSkew = TimeSpan.Zero
};
此对象在 public void ConfigureServices(IServiceCollection services)
方法中使用如下
services
.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.TicketDataFormat = new CustomJwtDataFormat(
SecurityAlgorithms.HmacSha256,
tokenValidationParameters);
});
尽量避免传递 IConfiguration。共享代码可以在 Startup 中完成,模型填充并添加到容器中
可以直接在Startup.ConfigureServices
中的容器中注册实例
void ConfigureServices(IServiceCollection services) {
var jwt_key = Configuration.GetSection("JwtOption:IssuerSigningKey").Value;
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwt_key));
var tokenValidationParameters = new TokenValidationParameters {
//...code omitted for brevity
}
services.AddSingleton(tokenValidationParameters);
//...can still use tokenValidationParameters
services
.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.TicketDataFormat = new CustomJwtDataFormat(
SecurityAlgorithms.HmacSha256,
tokenValidationParameters);
});
}
并在需要的地方显式注入
//ctr
public MyController(TokenValidationParameters tokenParameters) {
//...
}
或者您可以使用选项模式
引用Options pattern in ASP.NET Core
void ConfigureServices(IServiceCollection services) {
//...code omitted for brevity
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwt_key));
services.Configure<TokenValidationParameters>(options => {
// The signing key must match!
options.ValidateIssuerSigningKey = true;
options.IssuerSigningKey = signingKey;
// Validate the JWT Issuer (iss) claim
options.ValidateIssuer = true;
options.ValidIssuer = "some host name";
// Validate the JWT Audience (aud) claim
options.ValidateAudience = true;
options.ValidAudience = "web_intranet";
// Validate the token expiry
options.ValidateLifetime = true;
// If you want to allow a certain amount of clock drift, set that here:
options.ClockSkew = TimeSpan.Zero;
});
//...
//Use DI services to configure cookie options
var scheme = CookieAuthenticationDefaults.AuthenticationScheme;
services.AddOptions<CookieAuthenticationOptions>(scheme)
.Configure<IOptions<TokenValidationParameters>>((options, token) => {
options.TicketDataFormat = new CustomJwtDataFormat(
SecurityAlgorithms.HmacSha256,
token.Value); //<--
});
services
.AddAuthentication(scheme)
.AddCookie();
}
引用Use DI services to configure options
并在需要的地方注入 IOptions<TokenValidationParameters>
//ctr
public MyController(IOptions<TokenValidationParameters> options) {
TokenValidationParameters tokenParameters = options.Value;
//...
}
这是我使用 DI 测试的选项。
创建 POCO 对象:
public sealed class JwtConfig
{
public TokenValidationParameters tokenValidationParameters;
public JwtConfig(IConfiguration configuration)
{
// configure the object: tokenValidationParameters
}
}
在启动中:
public void ConfigureServices(IServiceCollection services)
{
// register
services.AddSingleton<JwtConfig>();
// retrieve
var serviceProvider = services.BuildServiceProvider();
var jwtConfig = serviceProvider.GetService<JwtConfig>();
// use the jwtConfig <IMPORTANT to be able to do this here>
}
在控制器构造函数中,注入对象:
public LoginController(IUserService userService, JwtConfig jwtConfig)
{
this.jwtConfig = jwtConfig;
}
在 ASP.NET Core 3.1 Startup class 和控制器之间共享配置对象的最佳方式是什么?
我看过一些使用 DI 的示例,这似乎是个好主意,但我需要使用 public void ConfigureServices(IServiceCollection services)
中的依赖项。
此外,该对象依赖于一个 Microsoft.Extensions.Configuration.IConfiguration
实例。
The object will be used within
Startup.cs
, within theConfigureServices
itself as well as inControllers
.
DI 有用吗?还是解决方案是带参数的单例?
这里是需要分享的具体代码:
// openssl rand -hex 16 => 256 bits when read
var jwt_key = Configuration.GetSection("JwtOption:IssuerSigningKey").Value;
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwt_key));
var tokenValidationParameters = new TokenValidationParameters
{
// The signing key must match!
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
// Validate the JWT Issuer (iss) claim
ValidateIssuer = true,
ValidIssuer = "some host name",
// Validate the JWT Audience (aud) claim
ValidateAudience = true,
ValidAudience = "web_intranet",
// Validate the token expiry
ValidateLifetime = true,
// If you want to allow a certain amount of clock drift, set that here:
ClockSkew = TimeSpan.Zero
};
此对象在 public void ConfigureServices(IServiceCollection services)
方法中使用如下
services
.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.TicketDataFormat = new CustomJwtDataFormat(
SecurityAlgorithms.HmacSha256,
tokenValidationParameters);
});
尽量避免传递 IConfiguration。共享代码可以在 Startup 中完成,模型填充并添加到容器中
可以直接在Startup.ConfigureServices
void ConfigureServices(IServiceCollection services) {
var jwt_key = Configuration.GetSection("JwtOption:IssuerSigningKey").Value;
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwt_key));
var tokenValidationParameters = new TokenValidationParameters {
//...code omitted for brevity
}
services.AddSingleton(tokenValidationParameters);
//...can still use tokenValidationParameters
services
.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.TicketDataFormat = new CustomJwtDataFormat(
SecurityAlgorithms.HmacSha256,
tokenValidationParameters);
});
}
并在需要的地方显式注入
//ctr
public MyController(TokenValidationParameters tokenParameters) {
//...
}
或者您可以使用选项模式
引用Options pattern in ASP.NET Core
void ConfigureServices(IServiceCollection services) {
//...code omitted for brevity
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwt_key));
services.Configure<TokenValidationParameters>(options => {
// The signing key must match!
options.ValidateIssuerSigningKey = true;
options.IssuerSigningKey = signingKey;
// Validate the JWT Issuer (iss) claim
options.ValidateIssuer = true;
options.ValidIssuer = "some host name";
// Validate the JWT Audience (aud) claim
options.ValidateAudience = true;
options.ValidAudience = "web_intranet";
// Validate the token expiry
options.ValidateLifetime = true;
// If you want to allow a certain amount of clock drift, set that here:
options.ClockSkew = TimeSpan.Zero;
});
//...
//Use DI services to configure cookie options
var scheme = CookieAuthenticationDefaults.AuthenticationScheme;
services.AddOptions<CookieAuthenticationOptions>(scheme)
.Configure<IOptions<TokenValidationParameters>>((options, token) => {
options.TicketDataFormat = new CustomJwtDataFormat(
SecurityAlgorithms.HmacSha256,
token.Value); //<--
});
services
.AddAuthentication(scheme)
.AddCookie();
}
引用Use DI services to configure options
并在需要的地方注入 IOptions<TokenValidationParameters>
//ctr
public MyController(IOptions<TokenValidationParameters> options) {
TokenValidationParameters tokenParameters = options.Value;
//...
}
这是我使用 DI 测试的选项。
创建 POCO 对象:
public sealed class JwtConfig
{
public TokenValidationParameters tokenValidationParameters;
public JwtConfig(IConfiguration configuration)
{
// configure the object: tokenValidationParameters
}
}
在启动中:
public void ConfigureServices(IServiceCollection services)
{
// register
services.AddSingleton<JwtConfig>();
// retrieve
var serviceProvider = services.BuildServiceProvider();
var jwtConfig = serviceProvider.GetService<JwtConfig>();
// use the jwtConfig <IMPORTANT to be able to do this here>
}
在控制器构造函数中,注入对象:
public LoginController(IUserService userService, JwtConfig jwtConfig)
{
this.jwtConfig = jwtConfig;
}