gpt4 book ai didi

c# - 以相同的 ConfigureServices 方法访问在 asp.net core 的 startup.cs 文件中的 ConfigureServices 中创建的单例

转载 作者:行者123 更新时间:2023-11-30 16:39:04 28 4
gpt4 key购买 nike

所以我一直在尝试以 JWT 分发的形式设置一个带有 token 身份验证的小型测试 api, token 分发部分按预期工作。

然而,由于我想让我的 JWT 服务的方法更通用,以允许对 token 进行不同类型的签名(因为我更喜欢私钥/公钥对),所以我尝试在 appsettings 文件中设置更多选项这将决定 token 的生成方式,我开始使用依赖注入(inject)加载这些设置,直到现在我几乎没有接触过。

所以当我想将我设置为单例的那些配置类(到目前为止我已经通读过的大多数指南都这样做了,所以我认为它有点正确)并在ConfigureServices 他们添加的方法,这样我就可以使用我认为应该设置的参数,因为我通过获取 appsettings 文件的一部分在上面配置了几行。

但是,一旦我尝试访问它们,我就什么也得不到了,而是留下了空值。

启动.cs

public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//the token config takes values from the appsettings.json file
var tokenConf = Configuration.GetSection("TokenConfiguration");
services.Configure<TokenConfiguration>(tokenConf);

//the signing credentials are assigned in the JwtTokenService constructor
var signingConf = new SigningConfiguration();
services.AddSingleton<SigningConfiguration>(signingConf);
//my token service
services.AddSingleton<IJwtTokenService, JwtTokenService>();

//i try to get hold of the actual values to use later on
var provider = services.BuildServiceProvider();
TokenConfiguration tc = provider.GetService<TokenConfiguration>();
SigningConfiguration sc = provider.GetService<SigningConfiguration>();

//i wanna use the values in here when i set the parameters for my authentication
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(x =>
{
x.Events = new JwtBearerEvents
{
OnTokenValidated = context =>
{
return Task.CompletedTask;
}
};

x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
//values used here since i specify issuer, audience and what kind of key to use in the settings
//the key & credentials differ based on a bool in the settings file and will either be a symmetric or asymmetric key
ValidIssuer = tc.Issuer,
ValidAudience = tc.Audience,
IssuerSigningKey = sc.Key
};
});

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}

app.UseHttpsRedirection();
app.UseMvc();
}
}

JwtTokenService.cs(IJwtTokenService只有CreateToken方法在这里实现)

public class JwtTokenService : IJwtTokenService
{
private TokenConfiguration tokenConf;
public SigningConfiguration signingConf;

public JwtTokenService(IOptions<TokenConfiguration> tc) {
tokenConf = tc.Value;
signingConf = new SigningConfiguration();

//if the asymmetric bool is set to true, assign a new rsa keypair to the signing configuration
//otherwise, use a symmetric key with a hmac hash
if (tc.Value.AsymmetricKey)
{
using (var provider = new RSACryptoServiceProvider(2048))
{
signingConf.Key = new RsaSecurityKey(provider.ExportParameters(true));
}

signingConf.SigningCredentials =
new SigningCredentials(
signingConf.Key,
SecurityAlgorithms.RsaSha256);
}
else {
signingConf.Key =
new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(tc.Value.HmacSecret));

signingConf.SigningCredentials =
new SigningCredentials(
signingConf.Key,
SecurityAlgorithms.HmacSha512);
}
}

/// <summary>
/// Creates a token based on the running configuration
/// </summary>
public string CreateToken(List<Claim> claims)
{
var token = new JwtSecurityToken(
issuer: tokenConf.Issuer,
audience: tokenConf.Audience,
claims: claims,
expires: DateTime.UtcNow.AddMinutes(tokenConf.Minutes),
signingCredentials: signingConf.SigningCredentials
);

return new JwtSecurityTokenHandler().WriteToken(token);
}
}

token 配置.cs

public class TokenConfiguration
{
public string Audience { get; set; }
public string Issuer { get; set; }
public int Minutes { get; set; }
public bool AsymmetricKey { get; set; }
public string HmacSecret { get; set; }
}

SigningConfiguration.cs

public class SigningConfiguration
{
public SecurityKey Key { get; set; }
public SigningCredentials SigningCredentials { get; set; }
}

应用设置.json

"TokenConfiguration": {
"Audience": "ExampleAudience",
"Issuer": "ExampleIssuer",
"Minutes": 30,
"AsymmetricKey": true,
"HmacSecret": "example-secret-top-secret-secret-is_secret"

(该项目在 asp.net core 2.1 中运行以防万一)

我是 DI 的新手,找不到很多用例与我相同的示例,而且大多数此类案例涉及实际服务,而不是通过 DI 添加“配置”类。

可能有更好的方法来做到这一点,我可能只是愚蠢,因为没有注意到或不知道要谷歌搜索什么才能得到正确的答案,很可能会观看/阅读一些关于 DI 的内容在此之后不管。

任何意见或想法都将不胜感激,因为我对 asp.net core 和整个流程还是陌生的。

作为关于私钥生成的一个小问题,在我的例子中,最好将生成的 key 对存储在 keystore 中,或者将其存储在内存中,或者通过 openSSL 之类的东西生成它们并从中读取在启动时是最佳选择吗?

最佳答案

您正在请求 TokenConfiguration而不是 IOptions<TokenConfiguration>来自服务提供商。更改此行

   TokenConfiguration tc = provider.GetService<TokenConfiguration>();
SigningConfiguration sc = provider.GetService<SigningConfiguration>();

    IOptions<TokenConfiguration> tc = provider.GetService<IOptions<TokenConfiguration>>();
IOptions<SigningConfiguration> sc = provider.GetService<IOptions<SigningConfiguration>>();

然后使用 tc.Value 访问选项.

建筑 ServiceProviderConfigureServices这不是一个好主意,我会通过 Configuration["TokenConfiguration:Audience"] 直接从配置中获取我需要的任何地方 ConfigureServices .

关于c# - 以相同的 ConfigureServices 方法访问在 asp.net core 的 startup.cs 文件中的 ConfigureServices 中创建的单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53707133/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com