使用 IdentityServer 的项目遭遇错误:"IDX20803: Unable to obt

2021-02-05 15:30发布

问题:

一个使用 IdentityServer 的 ASP.NET Core Web API 项目升级到 .NET 5.0 之后日志中出现下面的错误:

System.InvalidOperationException: IDX20803: Unable to obtain configuration from: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
 ---> System.IO.IOException: IDX20804: Unable to retrieve document from: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
 ---> System.Threading.Tasks.TaskCanceledException: The operation was canceled.
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
   --- End of inner exception stack trace ---
   at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
   at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(String address, IDocumentRetriever retriever, CancellationToken cancel)
   at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
   --- End of inner exception stack trace ---
   at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
   at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()

请问如何解决?

回答1:

将 Startup 中的 AddIdentityServerAuthentication 改为 AddJwtBearer + AddOAuth2Introspection,并且在 AddJwtBearer 中将 ValidateIssuer 选项设置为 false 后解决了

options.TokenValidationParameters.ValidateIssuer = false;

Startup.ConfigureServices 中 IdentityServer 的完整配置如下:

var webApiOptions = configuration.GetSection("IdentityServer").Get<WebApiOptions>();
services.AddAuthentication("token")
// JWT tokens
.AddJwtBearer("token", options =>
{
    options.Authority = webApiOptions.Authority;
    options.Audience = webApiOptions.ApiName;
    options.TokenValidationParameters.ValidTypes = new[] { "at+jwt" };
    options.TokenValidationParameters.ValidateIssuer = false;
    options.RequireHttpsMetadata = false;
    // if token does not contain a dot, it is a reference token
    options.ForwardDefaultSelector = IdentityModel.AspNetCore.AccessTokenValidation.Selector.ForwardReferenceToken("introspection");
})
// reference tokens
.AddOAuth2Introspection("introspection", options =>
{
    options.Authority = webApiOptions.Authority;
    options.ClientId = webApiOptions.ApiName;
    options.ClientSecret = webApiOptions.ApiSecret;
    options.EnableCaching = true;
    options.DiscoveryPolicy.ValidateIssuerName = false;
});

园子里的参考博文:IdentityServer4 关于 AddIdentityServerAuthentication 方法