动态配置身份验证
[上下文]
我正在测试身份提供者。我遇到了一个有趣的场景,其中......内省端点仍然缺失,这意味着我将自己验证令牌,如下所示:
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add(HeaderNames.Accept, "application/json");
var response = await client.GetAsync("url_to_jwks");
var content = await response.Content.ReadAsStringAsync();
var jwk = new JsonWebKeySet(content).GetSigningKeys().First();
services.AddAuthentication()
.AddJwtBearer("SelfValidationKey", opt =>
{
opt.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateIssuerSigningKey = true,
IssuerSigningKey = jwk
};
opt.RequireHttpsMetadata = false;
});
services.AddOcelot();
当然还有其他参数需要检查,但为了简单起见,我们将只需关注签名,因为这也是我的问题:)
[想法]
与其使用证书进行验证,为什么不使用 IdP 众所周知的文档提供的 jwk(jwk 并不总是相同的)。这就是我所做的,而且有效,但是!当我尝试在配置服务中进行 http 调用时,在添加身份验证之前,它会崩溃:
System.NullReferenceException:未将对象引用设置为对象的实例。 在 Ocelot.Middleware.OcelotMiddlewareExtensions.CreateConfiguration(IApplicationBuilder 构建器) 在 Ocelot.Middleware.OcelotMiddlewareExtensions.UseOcelot(IApplicationBuilder 构建器,OcelotPipelineConfiguration pipelineConfiguration) 在 Ocelot.Middleware.OcelotMiddlewareExtensions.UseOcelot(IApplicationBuilder 构建器) 在 ApiGateway.Startup.Configure
我以为我无法在我的服务配置中进行 http 调用,但实际上我检查了并且确实收到了我期望的响应。我已经在不同的startup.cs上尝试过了,它工作得很好,所以我猜......它与Ocelot(api网关)有关,我是否以错误的方式制作了async/await语句?异常是在 Programs .cs 中引发的,这是非常基本的,我从未达到 Services.AddAuthentication():
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args)
{
var builder = WebHost.CreateDefaultBuilder(args);
builder.ConfigureServices(s => s.AddSingleton(builder))
.ConfigureAppConfiguration(
ic => ic.AddJsonFile("ocelot.json"))
.UseStartup<Startup>();
var host = builder.Build();
return host;
}
[Context]
I'm testing an identity provider. And I came across an intriguing scenario where ... the introspect endpoint was still missing which means, i'm going to validate the token by myself like so:
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add(HeaderNames.Accept, "application/json");
var response = await client.GetAsync("url_to_jwks");
var content = await response.Content.ReadAsStringAsync();
var jwk = new JsonWebKeySet(content).GetSigningKeys().First();
services.AddAuthentication()
.AddJwtBearer("SelfValidationKey", opt =>
{
opt.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateIssuerSigningKey = true,
IssuerSigningKey = jwk
};
opt.RequireHttpsMetadata = false;
});
services.AddOcelot();
There are others parameters to check of course, but just for simplicity, we'll just focus on the signature, and because that's also my problem :)
[The idea]
Instead of verifying it with a certificate, why not use the jwk provided by the IdP well-known document (the jwk is not always the same). And that's what I did, and it works, but! When I try to make an http call inside my configure services, before adding authentification, it crashes:
System.NullReferenceException: Object reference not set to an instance of an object.
at Ocelot.Middleware.OcelotMiddlewareExtensions.CreateConfiguration(IApplicationBuilder builder)
at Ocelot.Middleware.OcelotMiddlewareExtensions.UseOcelot(IApplicationBuilder builder, OcelotPipelineConfiguration pipelineConfiguration)
at Ocelot.Middleware.OcelotMiddlewareExtensions.UseOcelot(IApplicationBuilder builder)
at ApiGateway.Startup.Configure
I thought I couldn't make http calls inside my service configuration, but acutally I checked and I do receive the response I was expecting. I've tried it on a different startup.cs and it works just fine, so my guess ... it has to do with Ocelot (api gateway) somehow, am I making the async/await statement in the wrong way? The exception is thrown at Programs .cs which is very basic, and I never reach Services.AddAuthentication():
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args)
{
var builder = WebHost.CreateDefaultBuilder(args);
builder.ConfigureServices(s => s.AddSingleton(builder))
.ConfigureAppConfiguration(
ic => ic.AddJsonFile("ocelot.json"))
.UseStartup<Startup>();
var host = builder.Build();
return host;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
一种方法是...
通过我的program.cs中的静态类IdpDocument进行调用,通过UseSetting方法将我需要的值传递给配置,然后将其注入到startup.cs中,它看起来像这样:
在我的startup.cs中,我得到的值:
但是......我唯一关心的是......我只发出一次请求。那么,如果 jwks 更新了怎么办? (这不是该程序的责任)
获得正确密钥的唯一方法是重新运行该程序,该程序并不是真正干净。
One way was to ...
Make a call through my static class IdpDocument in my program.cs, pass the value I need to the configuration via UseSetting method, which is then injected into the startup.cs, and it looks like this:
And in my startup.cs, i get the value:
But ... my only concern with that is .. I only make the request once. So, what if the jwks get updated? (which is not this program responsibility)
The only way to get the right keys, is to re-run this program which .. is not really clean.