前言:

在部署Idv4站点和其客户端在外网时,发现了许多问题,折腾了许久,翻看了许多代码,写个MD记录一下。

1.受保护站点提示错误: Unable to obtain configuration from: '[PII is hidden]'.

fail: Microsoft.AspNetCore.Server.Kestrel[13]Connection id "0HLL3MB34N0G5", Request id "0HLL3MB34N0G5:00000009": An unhandled exception was thrown by the application.
System.InvalidOperationException: IDX20803: Unable to obtain configuration from: '[PII is hidden]'.在 Microsoft.IdentityModel.Protocols.ConfigurationManager`1.<GetConfigurationAsync>d__24.MoveNext()
--- 引发异常的上一位置中堆栈跟踪的末尾 ---在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)在 Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.<HandleChallengeAsync>d__18.MoveNext()
--- 引发异常的上一位置中堆栈跟踪的末尾 ---在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)在 Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.<ChallengeAsync>d__54.MoveNext()
--- 引发异常的上一位置中堆栈跟踪的末尾 ---
1.1 受保护站点的代码执行流程
graph TB
User--1.进入-->A(Home/Index)
A--2.Authorize-->AA{是否授权}
AA--YES-->完事
AA--NO-->B(返回ChallengeResult)
B--3.ExecuteResult-->C(进入AuthenticationMiddleware中间件)
C--4.根据authenticationScheme找到相应Handler-->D(OpenIDConenctHandler)
D--5.调用HandleChallengeAsync-->F(调用OpenIdConnectConfigurationRetriever.IConfigurationRetriever)
F--6.通过HTTP调用Idv4站点的/.well-known/openid-configuration-->F1(Idv4Config)
F1--7.通过上步骤取到的config.jwks_uri获取加密key信息-->F2(获得公钥私钥等信息)
F2--8.设置JsonWebKeySet-->F3(完成openIdConnectConfiguration.SigningKeysKeys的添加)
F3-->F4(完成)

1.1 受保护站点的部分源码

Idv4部分源码

//注入Idev相关,配置authenticationScheme为oidc
public static IIdentityServerBuilder AddIdentityServer(this IServiceCollection services, Action<IdentityServerOptions> setupAction)
{services.Configure(setupAction);return services.AddIdentityServer();
}

PS: 这里要额外提一下,在Abp的模板项目中,如下配置使用Idv4可能无法正常跳转IDV4授权站完成单点登录

services.AddOpenIdConnect("oidc", options =>
{...
}

需要额外添加下面这段,原因是Abp引入Microsoft.Identity,会重复设置schme导致错误,需如下代码添加设置。

services.AddAuthentication(options =>
{options.DefaultAuthenticateScheme = "oidc";options.DefaultChallengeScheme = "oidc";options.DefaultSignOutScheme = "oidc";
})

步骤5部分源码

 protected override async Task HandleChallengeAsync(AuthenticationProperties properties){Logger.EnteringOpenIdAuthenticationHandlerHandleUnauthorizedAsync(GetType().FullName);// order for local RedirectUri// 1. challenge.Properties.RedirectUri// 2. CurrentUri if RedirectUri is not set)if (string.IsNullOrEmpty(properties.RedirectUri)){properties.RedirectUri = CurrentUri;}Logger.PostAuthenticationLocalRedirect(properties.RedirectUri);if (_configuration == null && Options.ConfigurationManager != null){//问题在这里_configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.RequestAborted);}...

步骤6部分源码

 public static async Task<OpenIdConnectConfiguration> GetAsync(string address, IDocumentRetriever retriever, CancellationToken cancel){if (string.IsNullOrWhiteSpace(address))throw LogHelper.LogArgumentNullException(nameof(address));if (retriever == null){throw LogHelper.LogArgumentNullException(nameof(retriever));}//当站点没启动的时候,这里可能出现问题string doc = await retriever.GetDocumentAsync(address, cancel).ConfigureAwait(false);LogHelper.LogVerbose(LogMessages.IDX21811, doc);OpenIdConnectConfiguration openIdConnectConfiguration = JsonConvert.DeserializeObject<OpenIdConnectConfiguration>(doc);if (!string.IsNullOrEmpty(openIdConnectConfiguration.JwksUri)){LogHelper.LogVerbose(LogMessages.IDX21812, openIdConnectConfiguration.JwksUri);//当证书配置或读取错误的时候,这里会出现问题string keys = await retriever.GetDocumentAsync(openIdConnectConfiguration.JwksUri, cancel).ConfigureAwait(false);LogHelper.LogVerbose(LogMessages.IDX21813, openIdConnectConfiguration.JwksUri);openIdConnectConfiguration.JsonWebKeySet = JsonConvert.DeserializeObject<JsonWebKeySet>(keys);foreach (SecurityKey key in openIdConnectConfiguration.JsonWebKeySet.GetSigningKeys()){openIdConnectConfiguration.SigningKeys.Add(key);}}return openIdConnectConfiguration;}

通过流程进行问题解析:

通过查看日志可发现在流程5后开始报错

步骤一

访问:http://{ssoHost}/.well-known/openid-configuration

如果访问成功,则排除单点登录站点部署失败问题,前往步骤二

如果访问失败,则去解决单点登录站点部署问题。

步骤二

http://{ssoHost}/.well-known/openid-configuration/jwks

如果访问成功,则重启客户端

如果访问失败,那么有意思了...继续往下看

###### 此时单点登录站点的日志

[10:25:24 Error] Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware
An unhandled exception has occurred while executing the request.
Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: 出现了内部错误。at Internal.Cryptography.Helpers.OpenStorageProvider(CngProvider provider)at System.Security.Cryptography.CngKey.Import(Byte[] keyBlob, String curveName, CngKeyBlobFormat format, CngProvider provider)at System.Security.Cryptography.CngKey.Import(Byte[] keyBlob, CngKeyBlobFormat format)at Internal.Cryptography.Pal.X509Pal.DecodePublicKey(Oid oid, Byte[] encodedKeyValue, Byte[] encodedParameters, ICertificatePal certificatePal)at System.Security.Cryptography.X509Certificates.PublicKey.get_Key()at Microsoft.IdentityModel.Tokens.X509SecurityKey.get_PublicKey()at IdentityServer4.ResponseHandling.DiscoveryResponseGenerator.CreateJwkDocumentAsync()at IdentityServer4.Endpoints.DiscoveryKeyEndpoint.ProcessAsync(HttpContext context)at IdentityServer4.Hosting.IdentityServerMiddleware.Invoke(HttpContext context, IEndpointRouter router, IUserSession session, IEventService events)at IdentityServer4.Hosting.IdentityServerMiddleware.Invoke(HttpContext context, IEndpointRouter router, IUserSession session, IEventService events)at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)at IdentityServer4.Hosting.BaseUrlMiddleware.Invoke(HttpContext context)at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)

##### 单点登录站点在此时的工作流程

graph TBA(通过Http获取发现服务的配置信息)--1.进入SSO站点-->B(IdentityServerMiddleware)
B--2.调用Process-->C(进入DiscoveryKeyEndpoint)
C--3.遍历注入的加密Key-->D(返回JsonBWebKey)
部分源码解析:

   public async Task Invoke(HttpContext context, IEndpointRouter router, IUserSession session, IEventService events){// this will check the authentication session and from it emit the check session// cookie needed from JS-based signout clients.await session.EnsureSessionIdCookieAsync();try{//根据请求路径,进入相应endpoint处理器var endpoint = router.Find(context);if (endpoint != null){_logger.LogInformation("Invoking IdentityServer endpoint: {endpointType} for {url}", endpoint.GetType().FullName, context.Request.Path.ToString());var result = await endpoint.ProcessAsync(context);...
  //创建JwtDocumentpublic virtual async Task<IEnumerable<Models.JsonWebKey>> CreateJwkDocumentAsync(){var webKeys = new List<Models.JsonWebKey>();var signingCredentials = await Keys.GetSigningCredentialsAsync();var algorithm = signingCredentials?.Algorithm ?? Constants.SigningAlgorithms.RSA_SHA_256;foreach (var key in await Keys.GetValidationKeysAsync()){if (key is X509SecurityKey x509Key){var cert64 = Convert.ToBase64String(x509Key.Certificate.RawData);var thumbprint = Base64Url.Encode(x509Key.Certificate.GetCertHash());//当证书读取不正常的时候,PublicKey的属性构造器中会报错。var pubKey = x509Key.PublicKey as RSA;var parameters = pubKey.ExportParameters(false);var exponent = Base64Url.Encode(parameters.Exponent);var modulus = Base64Url.Encode(parameters.Modulus);var webKey = new Models.JsonWebKey{kty = "RSA",use = "sig",kid = x509Key.KeyId,x5t = thumbprint,e = exponent,n = modulus,x5c = new[] { cert64 },alg = algorithm};webKeys.Add(webKey);continue;}
问题解析

通过日志可发现,问题出现在PublicKey的获取上,即证书的读取失败了。

解决方案!

终于到解决问题的时候了...

步骤一:

检查证书是否是临时证书

//在正式环境中,这可能会报错
builder.AddDeveloperSigningCredential(true, "tempkey.rsa");//正确方式
builder.AddSigningCredential(new X509Certificate2(path,Configuration["Certificates:Password"]))
这里可以参见郭的随笔:
https://www.cnblogs.com/guolianyu/p/9872661.html                        
步骤二:

如果已经添加了证书,且证书路径正确读取,且证书密码正确;

但是!在Windows Server2008服务器上部署仍失败时请检查 CNG Key Isolation 服务是否启动!

如果 该服务未启动,则启动后即可!

如果该服务已启动,则尴尬的很...如果您仍排除不了问题,可以评论告诉我

转载于:https://www.cnblogs.com/Imaigne/p/10519493.html

IdentityServer4环境部署失败分析贴(一)相关推荐

  1. ELK实时日志分析平台环境部署--完整记录

    在日常运维工作中,对于系统和业务日志的处理尤为重要.今天,在这里分享一下自己部署的ELK(+Redis)-开源实时日志分析平台的记录过程(仅依据本人的实际操作为例说明,如有误述,敬请指出)~ ==== ...

  2. vTPM架构分析与环境部署

    (文章来源:vTPM架构分析与环境部署 - Linux系统教程 http://www.linuxdiyf.com/linux/22731.html) 概述 可信平台模块(Trusted Platfor ...

  3. kafka 基础知识梳理及集群环境部署记录

    一.kafka基础介绍 Kafka是最初由Linkedin公司开发,是一个分布式.支持分区的(partition).多副本的(replica),基于zookeeper协调的分布式消息系统,它的最大的特 ...

  4. MySQL高可用方案-PXC环境部署记录

    之前梳理了Mysql+Keepalived双主热备高可用操作记录,对于mysql高可用方案,经常用到的的主要有下面三种: 一.基于主从复制的高可用方案:双节点主从 + keepalived 一般来说, ...

  5. Linux下开源邮件系统Postfix+Extmail+Extman环境部署记录

    一.基础知识梳理 MUA (Mail User Agent)  MUA 既是"邮件使用者代理人",因为除非你可以直接利用类似 telnet 之类的软件登入邮件主机来主动发出信件,否 ...

  6. 【流媒体服务器Mediasoup】环境部署与demo搭建(二)

    目录 前言 服务器环境 NodeJs的安装 下载Demo源码 配置服务端 部署及测试 可能会遇到的问题 前言 上篇文章对MediaSoup进行简单的介绍  [MediaSoup]多人音视频架构.流媒体 ...

  7. SpringBoot与ElasticSearch、ActiveMQ、RocketMQ的整合及多环境配置、响应式框架WebFlux、服务器端主动推送SSE技术、生产环境部署、Actuator监控平台

    1.SpringBoot 与 ElasticSearch 框架的整合 (1)主要的搜索框架:MySQL.Solr.ElasticSearch MySQL:使用 like 进行模糊查询,存在性能问题 S ...

  8. Day133.尚品汇:项目介绍、Linux软件环境部署、项目环境搭建、表设计

    目录 一.电商项目介绍 二.Linux 软件环境部署 三.项目环境搭建 1.Maven 回顾 2.ElasticSearch 四.关于表设计 首页分类表 一.电商项目介绍 我们为什么要讲电商? 1. ...

  9. windows驱动数字签名之WHQL完整流程 | WHQL认证环境部署以及HLK测试

    文章目录 第一部分:windows驱动数字签名之WHQL完整流程 一.驱动数字签名背景 二.驱动程序数字签名解决方案-WHQL认证 1. 对开发者的影响 2. WHQL认证主要作用 三.申请WHQL认 ...

最新文章

  1. 使用属性position:fixed的时候如何才能让div居中
  2. mysql大表迁移_MySQL 大表迁移
  3. Android 屏幕自动旋转-Sensor属性
  4. Solr配置IK分词器
  5. BZOJ 3195: [Jxoi2012]奇怪的道路 | 状压DP
  6. linux删除空行 基本操作
  7. 22行代码AC_试题 历届试题 油漆面积【解题报告】
  8. GDB下查看内存命令(x命令)
  9. [ BZOJ 4668 ] 冷战
  10. 允许使用抽象类类型 isearchboxinfo 的对象_此对象非彼对象(面向对象)3
  11. okhttp配置缓存策略_一网打尽OkHttp中的缓存问题
  12. 57.Linux/Unix 系统编程手册(下) -- SOCKET : Unix domain
  13. 理解createTrackbar函数
  14. MySQL数据库企业级应用实践(主从复制)
  15. 优矿 pandas plt 显示平安银行基金月最大召回率
  16. 计算机系统的图像编码方式,彩色图像编码方案
  17. 智能BI,如今走到了哪一步?
  18. pe重装系统后F盘无法打开系统拒绝访问解决方案
  19. 车贷需要注意的问题,车贷风控流程这几点你必须知道
  20. labview编程笔记之条件结构

热门文章

  1. 宜搭数字工厂,让订单周期缩减三分之一
  2. 新内容,新交互”全球视频云创新挑战
  3. 履约时间预估:如何让外卖更快送达?
  4. 《阿里巴巴JAVA开发手册》发布详尽版,新增16条设计规约
  5. 从零开始做一个SLG游戏(二):用mesh实现简单的地形
  6. 使命召唤手游新的狙击枪,升级之后堪比巴雷特?会玩的就是
  7. Linux从零开始(一、安装系统)
  8. Linux操作系统知识
  9. 学习MongoDB 十一: MongoDB聚合(Aggregation Pipeline基础篇上)(三)
  10. 怎么设置电脑锁屏不断网