我有一个 ASP.NET Core Web API 项目,其中初始化代码位于
Program.cs
中,我需要设置 JWT 身份验证,并且在那里我需要设置 IssuerSigningKey
,它是从 SQL 数据库获取的,因为我使用 .NET Core / EF dataprotection
库自动生成和更新密钥。我面临的问题是我必须手动创建新的DbContext
,而不是能够使用依赖注入,以下是我的代码,想知道这是否是实现我的目标的合法方法
var contextOptions = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseSqlServer(connectionString, x => x.UseNetTopologySuite())
.Options;
OperationalStoreOptions storeOptions = new OperationalStoreOptions();
IOptions<OperationalStoreOptions> operationalStoreOptions = Options.Create(storeOptions);
var context = new ApplicationDbContext(contextOptions, operationalStoreOptions);
SymmetricSecurityKey securitykey = null;
var keyDb = context.DataProtectionKeys.FirstOrDefault();
if (keyDb == null || keyDb.Xml == null)
{
throw new ArgumentException("security key missing!");
}
else
{
XDocument keyDoc = XDocument.Parse(keyDb.Xml);
string keyAsStr = keyDoc.Descendants("value").First().ToString();
byte[] keyAsBytes = Encoding.UTF8.GetBytes(keyAsStr);
securitykey = SymmetricSecurityKey(keyAsBytes);
}
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters {
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "****",
ValidAudience = "****",
IssuerSigningKey = securitykey
};
});
我不知道你的 ApplicationDbContext 对第二个参数做了什么,但我认为它可以通过一种简单的方式完成。我的想法是向您的模型添加一个新类和一个新接口:
public interface IMyService
{
IOptions<OperationalStoreOptions> GetOptions();
}
public class MyService : IMyService
{
public IOptions<OperationalStoreOptions> GetOptions()
{
OperationalStoreOptions storeOptions = new OperationalStoreOptions();
return Options.Create(storeOptions);
}
}
然后你可以在你的Startup.cs中添加DI:
services.AddDbContext<MyContext>(options => options.UseSqlServer(connectionString, x => x.UseNetTopologySuite()));
services.AddScoped<IMyService, MyService>();
最后,我们不要忘记在 ApplicationDbContext 构造函数中添加引用:
public class ApplicationDbContext : DbContext
{
private readonly IOptions<OperationalStoreOptions> _operationalStoreOptions;
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, IMyService operationalStoreOptions) : base(options)
{
_operationalStoreOptions = operationalStoreOptions.GetOptions();
}
....your code (DbSet,...)
}