问题描述
我正在将ASP.NET Core 2.1与JwtBearer方案一起用于身份验证,如下所示:
I'm using ASP.NET Core 2.1 with the JwtBearer scheme for authentication, like so:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(o =>
{
// my options here
});
}
相当标准,但是我遇到的麻烦是我的令牌颁发机构发现端点需要访问权限的授权.我需要做的是将基本身份验证标头注入到JWT中间件对我的权限终结点所做的请求中.我正在查看配置选项,但看不到任何允许我执行此操作的东西.我还在查看源代码,看看是否可以看到在哪里发出了HTTP请求,但是通过抽象和扩展方法却将其混淆了,但我还没有找到它.
Pretty standard, however the hitch I've run into is my token authorities discovery endpoint requires authorization to access. What I need to do is inject a basic authentication header into the request the JWT middleware does to my authorities endpoint. I'm looking at the configuration options and I'm not seeing anything that allows me to do that. I'm also looking through the source code to see if I can see where the http request is being made but it's pretty obfuscated through abstraction and extension methods and I haven't found it yet.
有人可以告诉我是否可以在某处设置此地址,还是我必须创建自己的授权处理程序并将其手动捆绑在一起?任何建议表示赞赏.
Would anyone be able to tell me if it is possible to set this somewhere or will I have to create my own authorization handler and tie things together manually? Any advice is appreciated.
推荐答案
默认情况下,JwtBearer身份验证方案将使用ConfigurationManager
进行.well-known/openid-configuration
处的配置.如果您没有通过设置 JwtBearerOptions.ConfigurationManager
属性,则它将自动创建一个配置后:
By default, the JwtBearer authentication scheme will use a ConfigurationManager
for the configuration that’s exposed at .well-known/openid-configuration
. If you do not configure an instance explicitly by setting the JwtBearerOptions.ConfigurationManager
property, then it will automatically create one after your configuration:
var httpClient = new HttpClient(options.BackchannelHttpHandler ?? new HttpClientHandler());
httpClient.Timeout = options.BackchannelTimeout;
httpClient.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB
options.ConfigurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(options.MetadataAddress, new OpenIdConnectConfigurationRetriever(),
new HttpDocumentRetriever(httpClient) { RequireHttps = options.RequireHttpsMetadata });
您可以在此之前显式设置配置管理器,以使该代码不会运行.这样,您可以提供自己的实现或HttpClient
可以正确授权其请求.
You could explicitly set the configuration manager before, so that this code doesn’t run. That way, you can provide your own implementation or a HttpClient
that authorizes its requests properly.
如果您查看代码,还会有一个 BackchannelHttpHandler
.这是用于反向通道通信的HttpClientHandler
.反向通道请求是所有与授权机构通信的请求.因此,不仅是配置端点,还包括OAuth的userinfo端点之类的东西.由于JWT没有任何反向通道通信,因此在这种情况下您不必担心它,但是因为您也可以将其配置为例如OAuth,记住这一点很重要.
If you look at the code, there is also a BackchannelHttpHandler
. This is the HttpClientHandler
that is being used for backchannel communications. Backchannel requests are all those that communicate with the authority; so not only the configuration endpoint but also things like the userinfo endpoint for OAuth. Since JWT does not have any backchannel communication, you do not need to worry about it in this case, but since you can also configure that for e.g. OAuth, it’s important to keep it in mind.
因此,使用该BackchannelHttpHandler
,您可以例如指定凭据:
So using that BackchannelHttpHandler
, you can for example specify credentials:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(o =>
{
options.BackchannelHttpHandler = new HttpClientHandler()
{
UseDefaultCredentials = true,
};
// …
});
如果您需要其他凭据(例如使用Authorization
HTTP标头),则还可以提供自己的 DelegatingHandler
,可在将请求委派给普通的HttpClientHandler
之前添加HTTP标头.像这样:
If you need other credentials, for example using an Authorization
HTTP header, then you can also provide your own DelegatingHandler
that adds the HTTP header before delegating the request to the normal HttpClientHandler
. Something like this:
public class AuthorizingHandler : DelegatingHandler
{
private readonly string _headerValue;
public AuthorizingHandler(HttpMessageHandler inner, string headerValue)
: base(inner)
{
_headerValue = headerValue;
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
request.Headers.Add("Authorization", _headerValue);
return base.SendAsync(request, cancellationToken);
}
}
var innerHandler = new HttpClientHandler();
var headerValue = "Bearer foobar";
options.BackchannelHttpHandler = new AuthorizingHandler(innerHandler, headerValue);
另一种选择是直接使用 JwtBearerOptions.Configuration
.但是,当然,这需要您以其他方式将设置与权限同步,因此,它不是一个好选择.
Another alternative would be to just provide the configuration directly using JwtBearerOptions.Configuration
. But of course that requires you to sync the settings with the authority in other ways, so it likely isn’t a good option.
这篇关于JwtBearerHandler,带有用于发现端点的授权标头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!