.NetCore项目中集成了IdentityServer4,初始时使用http,获取token及API授权访问都ok。后面.netcore配置Kestrel使用https访问接口,出现了各种问题。
System.InvalidOperationException: IDX20803: Unable to obtain configuration from: '[PII is hidden]'.
---> System.IO.IOException: IDX20804: Unable to retrieve document from: '[PII is hidden]'.
---> System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo exception)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
可以看出来这些问题是和SSL证书有关,经过排查,发现IdentityServer4配置中:使用了IP:PORT的形式配置的授权地址,但是SSL证书是以域名形式申请的,这就造成了SSL证书不能验证通过。
解决方法:将授权地址配置为域名:端口的形式,完美解决上述问题。注意域名为SSL证书申请时用到的域名。
相关配置参数,如下示例:
Program.cs
public static void Main(string[] args)
{
...
...
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.ConfigureKestrel((context, options) =>
{
options.Listen(IPAddress.Any, 9999, listenOptions =>
{
listenOptions.UseHttps("SSL证书", "SSL证书密码");
});
})
.Build();
...
...
}
Startup.cs
public IServiceProvider ConfigureServices(IServiceCollection services)
{
...
...
//Config IdentityServer4
services.AddIdentityServer(options =>
{
options.PublicOrigin = "https://www.xxx.cn:9999";
})
.AddDeveloperSigningCredential()
.AddInMemoryApiResources(GetApiResources())
.AddInMemoryIdentityResources(GetIdentityResources())
.AddInMemoryClients(GetClients())
.AddResourceOwnerValidator<LoginValidator>()
.AddProfileService<ProfileService>();
//Configure IdentityServer4 Authority port
services.AddAuthorization();
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = "https://www.xxx.cn:9999";
//options.Authority = "https://localhost:9999";
options.ApiName = "api";
});
...
...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
...
...
//Add IdentityServer to the pipeline
app.UseIdentityServer();
...
...
}