关于 IdentityServer 部署到生产环境相关问题踩坑记录
Idsr 定义了几种模式适用于不同的场景:
//
// 摘要:
// OpenID Connect flows.
public enum Flows
{
//
// 摘要:
// authorization code flow
AuthorizationCode = ,
//
// 摘要:
// implicit flow
Implicit = ,
//
// 摘要:
// hybrid flow
Hybrid = ,
//
// 摘要:
// client credentials flow
ClientCredentials = ,
//
// 摘要:
// resource owner password credential flow
ResourceOwner = ,
//
// 摘要:
// custom grant
Custom = ,
//
// 摘要:
// authorization code with proof key flow
AuthorizationCodeWithProofKey = ,
//
// 摘要:
// hybrid flow with proof key
HybridWithProofKey =
}
最近我们把 IdentityServer 部署到了生成环境,为了适用于 cs/bs,app 等不同终端,接入使用了 OAuth2.0 标准规范 AuthorizationCode,ClientCredentials,ResourceOwner,Implicit 的几种模式和 OpenID Connect 协议,整个过程也遇到了各种各样的问题。
启用 HTTPS 后 Endpoint 问题
我们是在 LB 层部署了证书(没有设置在IIS层),IIS 层还是HTTP ,IdentityServer 默认 RequireSsl 强制设置成 false ,当时生成后的 Endpoints 都是 HTTP ,因为默认 IdentityServer 是根据 RequireSsl 的设置来生成URL;最后找到的解决方案是强制设置 PublicOrigin 为 HTTPS 的域名。
Terminating SSL
If you want to terminate SSL on the load balancer, there are two relevant settings on the options:
RequireSsl
Set this to false to allow non-SSL connections between the load balancer and IdentityServer.
PublicOrigin
Since your internal farm nodes have different names than the public reachable address, IdentityServer can’t use it for link generation. Set this property to the public name.
跨域与跳过权限确认页
CORS 是 Cross-Origin Resource Sharing 的缩写,这本质上来自于浏览器的保护机制。当web页面的host与Ajax访问的host不同时,浏览器会使用Http的 OPTIONS 方法,去探测被访问的host是否允许跨域访问。一般就是添加Access-Control-Allow-Origin的头 ,Idsrv 添加如下配置即可 。
RequireConsent = true,
AllowRememberConsent = true, RedirectUris = new List<string>
{
"http://localhost:5000/index.html",
}, AllowedCorsOrigins = new List<string>
{
"http://localhost:5000"
}
第三方资源问题
如果项目中引用了第三方的资源,需要设置
CspOptions = new CspOptions
{
Enabled = false,
}
负载环境切换缓存到 redis
//Redis
var redis = ConnectionMultiplexer.Connect(CacheSetting.Redis);
//客户端信息缓存
var clientStoreCache = new ClientStoreCache(redis);
//作用域信息缓存
var scopeStoreCache = new ScopeStoreCache(redis);
//用户信息缓存
var userServiceCache = new UserServiceCache(redis);
//注册客户端缓存-
factory.ConfigureClientStoreCache(new Registration<ICache<Client>>(clientStoreCache));
//注册作用域缓存
factory.ConfigureScopeStoreCache(new Registration<ICache<IEnumerable<Scope>>>(scopeStoreCache));
定期清理过期的票据(使用EF持久化票据)
var cleanToken = new TokenCleanup(ef, );
cleanToken.Start();
Token handle not found
-- ::18.9149 ERROR Token handle not found
{
"ValidateLifetime": true,
"AccessTokenType": "Reference",
"TokenHandle": "1d6f4eb15ca3079ac25978be95d7e2f5"
}
偶尔抽风,还没有找到解决方案
https://github.com/IdentityServer/IdentityServer3/issues/2985
https://github.com/IdentityModel/IdentityModel2
负载 XSRF 问题
做负载时需要配置 machineKey
the antiforgery token cookie is protected with the default Owin data protector. If, for some reason, the server does not manage to unprotect the cookie, it'll also treat the scenario as an antiforgery validation failed. In a load balanced environment, unless you take control of configuring the servers to use the same protectors (eg. common machine key), mismatch may happen.
https://github.com/IdentityServer/IdentityServer3/issues/450
https://github.com/IdentityServer/IdentityServer3/issues/1672
IDX10311: RequireNonce is 'true'
IDX10311: RequireNonce is 'true' (default) but validationContext.Nonce is null. A nonce cannot be validated. If you don't need to check the nonce, set OpenIdConnectProtocolValidator.RequireNonce to 'false'.
调试源码,这个错误是由于获取不到 cookie 的的原因,检查 idsrv 的站点 cookie 是否存在,是否使用 IE 并且 iframe 跨域(使用P3P协议自动更改IE浏览器安全级别:http://blog.csdn.net/fdipzone/article/details/43205961)
IDX10316: The 'nonce' has expired
Microsoft.IdentityModel.Protocols.OpenIdConnectProtocolInvalidNonceException
IDX10316: The 'nonce' has expired: '...'. Time from 'nonce': '19/01/2017 13:09:13', Current Time: '19/01/2017 15:48:05'. NonceLifetime is: '01:00:00'
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
// Set expiration time to 8 hours
ProtocolValidator = new OpenIdConnectProtocolValidator()
{
NonceLifetime = new TimeSpan(, , , )
},
... ,
AuthenticationFailed = (context) =>
{
if (context.Exception is OpenIdConnectProtocolInvalidNonceException && context.Exception.Message.ContainsAny(new string[] { "IDX10316", "IDX10311" }))
{
logger.Warn("OpenIdConnectProtocolInvalidNonce expired, reauthenticating...");
context.HandleResponse();
//context.Response.Redirect("/Error.aspx?message=" + context.Exception.Message);
context.Response.Redirect(context.Request.Uri.PathAndQuery);
}
return Task.FromResult();
},
https://teknovenus.com/nonce-expriation-idx10316-workaround-asp-net-mvc/
使用 OpenID Connect 登录成功回调白板
这个问题是上线后发现的,因为本地调试都是OK ,在公司网络访问也是OK(机房在公司,公司环境域名是做了内部 DNS 解析),就是外网不可以,各种日志看,排查了好几天;后面是发现,因为回调会 POST 相关的参数到客户端上,id_token 过长被防火墙截断,因为防火墙缓冲区设置太小的原因,参数如下:
id_token:eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImEzck1VZ01Gdjl0UGNsTGE2eUYzekFrZnF1RSIsImtpZCI6ImEzck1VZ01Gdjl0UGNsTGE2eUYzekFrZnF1RSJ9.eyJpc3MiOiJodHRwczovL3Nzby5jbG91ZGhvdGVscy5jbiIsImF1ZCI6IjEwMDAwMDA1IiwiZXhwIjoxNDk2NTYwMjA1LCJuYmYiOjE0OTY1NjAyMDQsIm5vbmNlIjoiNjM2MzIxNTY5OTYxOTU2NjM4Lk9EZGxaVEJrT1dJdFltVTRNaTAwT1RsaUxUazVaamt0TmpZMFlUa3dOams0TVRFME9EY3pNMk00WldVdE56SXlaaTAwWWpnd0xUbGhaREF0TTJOa05tRTNOelkyTXpKbCIsImlhdCI6MTQ5NjU2MDIwNCwiYXRfaGFzaCI6InJEYVhQcXRaSFZEcUxVSzhscmotUFEiLCJzaWQiOiJhNjBlMDA4NjUyMWU5OWMwOTkxMjJlOWQ1NGU2YTg3MCIsInN1YiI6ImlydmluZyIsImF1dGhfdGltZSI6MTQ5NjU2MDIwNCwiaWRwIjoiaWRzcnYiLCJ1c2VyIjoie1wiVXNlcklEXCI6XCJpcnZpbmdcIixcIlVzZXJOYW1lXCI6XCLlkajmtptcIixcIlVzZXJQd2RcIjpcIioqKioqKlwiLFwiU2FsdFwiOlwiKioqKioqXCIsXCJDaXR5QXJlYUlEXCI6XCIxMDAwMDAwOFwiLFwiQ2l0eUFyZWFOTVwiOlwi5Y2X5Y2O6KW_XCIsXCJDaXR5R3JvdXBJRFwiOlwiXCIsXCJDaXR5R3JvdXBOYW1lXCI6XCJcIixcIkpvYklEXCI6XCJBMDAwM1wiLFwiSm9iVGl0bGVcIjpcIuWfjuWMuumUgOWUruWJr-aAu-ebkVwiLFwiRW1haWxcIjpcInl4ZGVuZ0Bob21laW5ucy5jb21cIixcIkJ1c2luZXNzRGVwXCI6XCJcIixcIlVzZXJTb3VyY2VcIjozLFwiWFR5cGVcIjoyLFwiTW9iaWxlXCI6XCIxMzgxNzk2MzY2MlwiLFwiSG90ZWxDZFwiOlwiMDIxMDY0XCIsXCJIb3RlbE5hbWVcIjpcIuS4iua1t-WcuuS4rei3r-WcsOmTgeermeW6l--8iOWGheWuvu-8iVwiLFwiSG90ZWxKb2JJRFwiOlwiUkpDV0pMXCIsXCJIb3RlbEpvYlRpdGxlXCI6XCLotKLliqHnu4_nkIZcIixcIkJyYW5kQ2RcIjpcIlJKXCIsXCJCcmFuZERlc2NcIjpcIuWmguWutlwiLFwiVXBkYXRlVGltZVwiOlwiMjAxNy0wNS0xOFQwOTo0MDoyMS4wNFwifSIsImFtciI6WyJwYXNzd29yZCJdfQ.c_Dn0xxmLRGsp9_iZ7T2UOhwGf2uVjKwWYeGrKr70HtWDXcoafurb6_JxgEwdcWJzlhv3t9a-Y-LcupLbRBfBO-mP7CcbWM5Jr5zn55-z7RH2QnMlViK17AOOiXrKdCr8kTaGAK2bnkMpYIzk4oUAgWkwS3z0_RQ4G1aAIwIDxRvrKo4DuLwCXGPTYXp7YwAemnpvgywNvDM6yjKEL8KltdKyYWaHg8zxQVEPUOeteLFlsBA6rHJ873YTv-s6XNH3Rx944Sh75qGmPCkv3N3mEIDvHd8emMKyGJ53_Rbr6Jjr6eH_h8XNdwvtSIlH3GRfCgsJXppGxEl-KtRDGaR0w
access_token:eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImEzck1VZ01Gdjl0UGNsTGE2eUYzekFrZnF1RSIsImtpZCI6ImEzck1VZ01Gdjl0UGNsTGE2eUYzekFrZnF1RSJ9.eyJpc3MiOiJodHRwczovL3Nzby5jbG91ZGhvdGVscy5jbiIsImF1ZCI6Imh0dHBzOi8vc3NvLmNsb3VkaG90ZWxzLmNuL3Jlc291cmNlcyIsImV4cCI6MTQ5NjU2MDIwNSwibmJmIjoxNDk2NTYwMjA0LCJjbGllbnRfaWQiOiIxMDAwMDAwNSIsInNjb3BlIjpbIm9wZW5pZCIsInByb2ZpbGUiXSwic3ViIjoiaXJ2aW5nIiwiYXV0aF90aW1lIjoxNDk2NTYwMjA0LCJpZHAiOiJpZHNydiIsImFtciI6WyJwYXNzd29yZCJdfQ.e4DeFyh2Jt6dnsry0ALSbEJpj34lbN0u_iW9YAsc_XlSgWm044LeI19xRzgZvzF4lN_4jjwjvMaQPzOO4MOokSmSAjwnMdVg1j2b9U3c7YyqIUQMueHn1hTr06f2kd2OLYLz38RnNilvFf1xAAF8tXs2TOyrHl9L39i6Nb3I7pQenooIoIbP8yRGpGAztRVBBEHf-b1-7b1wmhaDYEKe_dFOXzlNPRjFzrDhvCcoke2SHJ3Zo60c9JQVUKopFPYUF0EN_TDsS4dHeZCE55tLb--1KJpz7e2WVNGMbts7HGUrlpa4O4mwESxN_c1F3V8YVstdEB7i8xYZCSqQHUdE4Q
token_type:Bearer
expires_in:1
scope:openid profile
state:OpenIdConnect.AuthenticationProperties=Tl--AjNJpswyb_R1ytC6SqEKnWP5FWe969jAIK-tPHj7l5bCYieg5fffC111-Bjur08jIafy5-DNg2ESrenp71it4OBCLnUsLXPbFGxlsT6jWwsTmRgJf5HxG-HtsTZm2iIwDkFl2P4GmlUt7GAl8gMuTNlaLqB3M-RuJ2prt603WzMQ
session_state:UDOKlCOQmRPUjrKy2bRKz-erQ9Ze4jkre7FwspSAZBA.d02260a76d5c74285e125e59531cea07
REFER: https://identityserver.github.io/Documentation/docsv2/advanced/deployment.html
关于 IdentityServer 部署到生产环境相关问题踩坑记录的更多相关文章
- 关于PHP索引数组unset某key后json_encode相关问题踩坑记录
<?php $a = [1,2,3]; var_dump(json_encode($a)); #string(7) "[1,2,3]" unset($a[0]); var_d ...
- 把Sharepoint Desinger 工作流部署到生产环境
下面是比较简单的方法,把Designer工作流从开发环境部署到生产环境. 在Sharepoint Desinger 2013 中点击需要部署的工作流. 点击保存,发布. 点Export to Visi ...
- Greenplum 数据库安装部署(生产环境)
Greenplum 数据库安装部署(生产环境) 硬件配置: 16 台 IBM X3650, 节点配置:CPU 2 * 8core,内存 128GB,硬盘 16 * 900GB,万兆网卡. 万兆交换机. ...
- 转_Greenplum 数据库安装部署(生产环境)
Greenplum 数据库安装部署(生产环境) 硬件配置: 16 台 IBM X3650, 节点配置:CPU 2 * 8core,内存 128GB,硬盘 16 * 900GB,万兆网卡. 万兆交换机. ...
- Mac系统STF自动化环境搭建及部署踩坑记录
因为公司需要寻找一个免root的自动化测试方案,所以以前做的老方案需要被替代.一阵搜寻找到了这个框架,但是部署起来很是折腾,搞了一下午终于搞定,顺便记录一下过程,有需要的自取. 转载请注明出处:htt ...
- Opencv环境配置及踩坑
Opencv环境配置及踩坑 1.什么是Opencv OpenCV是一个基于Apache2.0许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux.Windows.Android和[ ...
- Pytorch及Yolov5环境配置及踩坑
Pytorch及Yolov5环境配置及踩坑 1.何为Yolov5 yolo是计算机视觉方面用来进行目标检测的一个十分出名的开源框架,我搜不到官方的对此概括性的定义,但实际上也没什么必要,更重要的是会使 ...
- (转) 将ASP.NET Core应用程序部署至生产环境中(CentOS7)
原文链接: http://www.cnblogs.com/ants/p/5732337.html 阅读目录 环境说明 准备你的ASP.NET Core应用程序 安装CentOS7 安装.NET Cor ...
- 将ASP.NET Core应用程序部署至生产环境中(CentOS7)
这段时间在使用Rabbit RPC重构公司的一套系统(微信相关),而最近相关检验(逻辑测试.压力测试)已经完成,接近部署至线上生产环境从而捣鼓了ASP.NET Core应用程序在CentOS上的部署方 ...
随机推荐
- 服务器被minerd
cd /opt chmod -x minerd 去/root/.ssh 目录下,清除authorized_keys,KHK75NEOiq 文件 在ssh的配置文件/etc/ssh/sshd_confi ...
- v$lockv和$locked_object的区别
v$lockv和$locked_object的区别 url: http://blog.sina.com.cn/s/blog_62defbef0101pgvo.html 2013-12-24 v1.0 ...
- uasrt配置
Universal Synchronous/Asynchronous Receiver/Transmitter 同步是指:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式.同步要有一个 ...
- http响应头里没有或者有content-length的几种可能性
对于http的请求返回结果要进行内容的长度校验主要有两种方式,二者互斥使用 1.客户端在http头(head)加Connection:keep-alive时,服务器的response是Transfer ...
- MySQL DDL--ghost工具学习
GHOST工作流程图: GHOST工作原理: .首先新建一张ghost表,结构与源表相同 .使用alter命令修改ghost表 3.1.模拟从库命令获取主库上该表的binlog(基于全镜像的行模式的b ...
- IPv6技术详解:基本概念、应用现状、技术实践(下篇)
本文来自微信技术架构部的原创技术分享. 1.前言 在上篇<IPv6技术详解:基本概念.应用现状.技术实践(上篇)>,我们讲解了IPV6的基本概念. 本篇将继续从以下方面展开对IPV6的讲解 ...
- 16.IO之其他流
第一 打印流 一.概述: 该流提供了打印方法,可以将各种数据类型的数据都原样打印 原理; x<=3; x++){ al.add(new FileInputStream(x+".txt ...
- MySQL 字符集utf8和utf-8的关系
目录 什么是字符集(character set) 校对规则(collation) ASCII码 Unicode国际化支持 UTF-8 utf8 utf8与utf8mb4的关系 超集 字符集设置 什么是 ...
- 机器学习框架之sklearn简介
简介 今天为大家介绍的是scikit-learn.sklearn是一个Python第三方提供的非常强力的机器学习库,它包含了从数据预处理到训练模型的各个方面.在实战使用scikit-learn中可以极 ...
- 列表list切片
list1 = [1, 2, 3, 4, 5, 6] list1[::-1] >>>[6, 5, 4, 3, 2, 1] list1[:3:-1] >>>[6, 5 ...