IdentityServer 部署踩坑记

Intro

周末终于部署了 IdentityServer 以及 IdentityServerAdmin 项目,踩了几个坑,在此记录分享一下。

部署架构

项目是基于 IdentityServerAdmin 项目修改的,感谢作者的开源付出,有需要 IdentityServer 管理需求的可以关注一下,觉得好用的可以给个 star 支持一下 https://github.com/skoruba/IdentityServer4.Admin

实际部署的有两个服务,一个是 IdentityServer 项目(https://id.weihanli.xyz),一个是 IdentityAdmin 项目(<https://id-admin.weihanli.xyz>)。

两个服务都是部署在一台服务器上,这一台服务器上部署一个单节点的 kubernetes,两个服务都是部署在 k8s 上并通过 NortPort 的方式对外提供服务,外面有一层 nginx 做了请求转发同时提供对外 https 的支持。

最初的 nginx 配置如下

server {
listen 443;
ssl_certificate /home/pipeline/.acme.sh/*.weihanli.xyz/*.weihanli.xyz.cer;
ssl_certificate_key /home/pipeline/.acme.sh/*.weihanli.xyz/*.weihanli.xyz.key;
server_name id.weihanli.xyz; location / {
proxy_pass http://172.17.0.2:31210;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 443;
ssl_certificate /home/pipeline/.acme.sh/*.weihanli.xyz/*.weihanli.xyz.cer;
ssl_certificate_key /home/pipeline/.acme.sh/*.weihanli.xyz/*.weihanli.xyz.key;
server_name id-admin.weihanli.xyz; location / {
proxy_pass http://172.17.0.2:31211;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

IdentityServer重定向到内网地址

部署起来之后,IdentityServer 可以访问,但是 IdentityAdmin 访问的时候会重定向到 IdentityServer 去登录,在发生重定向的时候会重定向到内网地址,重定向到了 172.17.0.1:31210 这个内网地址,这个地址是一个内网地址,公网肯定是没有办法访问的,在网上 Google 了半天发现有个类似的问题 网络回流(NAT Loopback/ Hairpin NAT),大概就是在同一网段的内网中的两个服务通信的时候通过公网域名没有办法访问,会转换成内网IP访问,所以发生重定向的时候会出现原本是域名重定向但是却变成了内网IP(不确定我的这种情况是不是属于网络回流的情况,有网络大佬的话可以帮忙分析一下,万分感谢)

因为使用了 nginx 并且转发后的内网 IP 地址是 nginx 转发到的请求地址,所以又 Google 了 nginx proxy redirect 关键词,最后找到一个解决方案 https://unix.stackexchange.com/questions/290141/nginx-reverse-proxy-redirection

最后生效的 nginx 完整配置如下:

server {
listen 443 http2;
ssl_certificate /home/pipeline/.acme.sh/*.weihanli.xyz/*.weihanli.xyz.cer;
ssl_certificate_key /home/pipeline/.acme.sh/*.weihanli.xyz/*.weihanli.xyz.key; server_name id-admin.weihanli.xyz; location / {
proxy_pass http://172.17.0.2:31211;
proxy_redirect http://172.17.0.2:31210/ https://id.weihanli.xyz/;
proxy_set_header Host $host;
proxy_set_header Referer $http_referer;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

增加了上面的配置之后再发生重定向的时候地址就是正确的了,不再是一个内网IP 了

Invalid Token

Identity Server 重定向的问题解决之后,马上就出现了新的问题。。。

首先在 Identity Server 登录成功之后返回到 IdentityAdmin 的时候会报错,查看日志可以看到是 token 不合法的问题,起初是 issuer 不对的问题,我想可能是 issuer 可能 http/https 不一致的问题,于是增加了一个配置,直接在注册 IdentityServer 的时候使用指定的 issuer ,想着这样就不会有 http/https 的问题,于是重新部署,重新尝试之后,token 还是有问题,日志显示是token 签名验证错误,这时不经意之间看了一眼 IdentityServer 的 发现文档,打开之后发现里面的各种 endpoint 都是 http 的,后来发现 IdentityServer 有一个 PublicOrigin 的配置,把这个配置配置成 https://id.weihanli.xyz 之后就没有 invalid token 之类的错误了,再看发现文档的时候,endpoint 也是基于 https 的了。

Identity-Admin 502

IdentityServer 登录成功之后重定向到 IdentityAdmin 的时候 502,但是服务是存在的 在日志里只找到下面这样的错误日志

Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectProtocolException: Message contains error: 'invalid_grant' , error_description: 'error_description is null', error_uri: 'error_uri is null'

在网上 Google 之后找到了这个issue: https://github.com/IdentityServer/IdentityServer4/issues/1670,尝试了下面这个解决方案解决了,是因为重定向的时候请求信息太大了

nginx 中 IdentityAdmin 项目增加配置:

proxy_buffer_size          128k;

proxy_buffers              4 256k;

proxy_busy_buffers_size    256k;

修改之后,执行 sudo nginx -s reload 重新加载配置之后就正常了

More

最后现在在用的有效的完整的 nginx 配置如下:

server {
listen 443 http2;
ssl_certificate /home/pipeline/.acme.sh/*.weihanli.xyz/*.weihanli.xyz.cer;
ssl_certificate_key /home/pipeline/.acme.sh/*.weihanli.xyz/*.weihanli.xyz.key; server_name id.weihanli.xyz; location / {
proxy_pass http://172.17.0.2:31210;
proxy_redirect off; proxy_set_header Host $host;
proxy_set_header Referer $http_referer;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
} server {
listen 443 http2;
ssl_certificate /home/pipeline/.acme.sh/*.weihanli.xyz/*.weihanli.xyz.cer;
ssl_certificate_key /home/pipeline/.acme.sh/*.weihanli.xyz/*.weihanli.xyz.key; server_name id-admin.weihanli.xyz; location / {
proxy_pass http://172.17.0.2:31211;
proxy_redirect http://172.17.0.2:31210/ https://id.weihanli.xyz/;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
proxy_set_header Host $host;
proxy_set_header Referer $http_referer;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

Reference

IdentityServer 部署踩坑记的更多相关文章

  1. Spark踩坑记——数据库(Hbase+Mysql)

    [TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...

  2. Spark踩坑记——共享变量

    [TOC] 前言 Spark踩坑记--初试 Spark踩坑记--数据库(Hbase+Mysql) Spark踩坑记--Spark Streaming+kafka应用及调优 在前面总结的几篇spark踩 ...

  3. Spark踩坑记——从RDD看集群调度

    [TOC] 前言 在Spark的使用中,性能的调优配置过程中,查阅了很多资料,之前自己总结过两篇小博文Spark踩坑记--初试和Spark踩坑记--数据库(Hbase+Mysql),第一篇概况的归纳了 ...

  4. [转]Spark 踩坑记:数据库(Hbase+Mysql)

    https://cloud.tencent.com/developer/article/1004820 Spark 踩坑记:数据库(Hbase+Mysql) 前言 在使用Spark Streaming ...

  5. Spark踩坑记——数据库(Hbase+Mysql)转

    转自:http://www.cnblogs.com/xlturing/p/spark.html 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库 ...

  6. Spring @Transactional踩坑记

    @Transactional踩坑记 总述 ​ Spring在1.2引入@Transactional注解, 该注解的引入使得我们可以简单地通过在方法或者类上添加@Transactional注解,实现事务 ...

  7. windows container 踩坑记

    windows container 踩坑记 Intro 我们有一些服务是 dotnet framework 的,不能直接跑在 docker linux container 下面,最近一直在折腾把它部署 ...

  8. Vue + TypeScript + Element 搭建简洁时尚的博客网站及踩坑记

    前言 本文讲解如何在 Vue 项目中使用 TypeScript 来搭建并开发项目,并在此过程中踩过的坑 . TypeScript 具有类型系统,且是 JavaScript 的超集,TypeScript ...

  9. WinUI 3 踩坑记:从创建项目到发布

    本文是 WinUI 3 踩坑记 的一部分,该系列发布于 GitHub@Scighost/WinUI3Keng,若内容出现冲突以 GitHub 上的为准. 创建项目 现在 WinUI 3 的入门体验比刚 ...

随机推荐

  1. 关于Html+css阶段学习总结

    一.学习经历 进入大学不久,就加入了社团,从而对前端有了一个初步的了解,之后也做过一些学校的官网,积累了一些微小的经验. 到了大二的时候,学校开设了专门的html+css课程,从中也学到许多新的htm ...

  2. C++冒险攻略(持续更新中。。。)

    C++语言程序设计 我的C++冒险之旅 绪论 计算机系统基本概念 计算机硬件 计算机程序语言 计算机解决问题是程序控制的 程序就是操作步骤 程序要使用语言来表达 机器语言 计算机能识别的是机器语言 机 ...

  3. GPS同步时钟装置应用及选择

    GPS同步时钟装置应用及选择 GPS是全球定位系统的简称,GPS具有全天时.全天候.高精度.定位和授时服务,GPS卫星授时成本低.安全可靠.覆盖范围广.GPS同步时钟装置,是指从GPS卫星上获取时间信 ...

  4. 序列化器:ModelSerializer

    ModelSerializer 类提供了一个快捷方式,可让你基于 Models 自动创建一个 Serializer 类,其中的字段与模型类字段对应. ModelSerializer 类与常规 Seri ...

  5. 5.创建app、创建user表、配置media、数据迁移

    目录 user模块User表 创建user模块 创建User表对应的model:user/models.py 注册user模块,配置User表:dev.py 配置media 数据库迁移 user模块U ...

  6. keep-alive 必须 页面有name 要不缓存不住数据

    keep-alive 必须 页面有name 要不缓存不住数据

  7. 浅谈 HTTP中Get与Post的区别

    浅谈 HTTP中Get与Post的区别 存在的误区 有人说 HTTP 协议下的 Get 请求参数长度是有大小限制的,最大不能超过XX,而 Post 是无限制的,看到这里,我想他们定是看多了一些以讹传讹 ...

  8. 创建和存储 cookie

    在这个例子中我们要创建一个存储访问者名字的 cookie.当访问者首次访问网站时,他们会被要求填写姓名.名字会存储于 cookie 中.当访问者再次访问网站时,他们就会收到欢迎词. 首先,我们会创建一 ...

  9. Jenkins的制品管理

    Jenkins的制品管理 制品是什么? 也叫产出物或工件.制品是软件开发过程中产生的多种有形副产品之一.广义的制品包括用例.UML图.设计文档等.而狭义的制品就可以简单地理解为二进制包.虽然有些代码是 ...

  10. SpringMVC框架——文件的上传与下载

    使用SpringMVC框架做个小练习,需求: 1.单个图片上传并显示到页面中: 2.多个图片上传并显示到页面中: 3.上传文件后下载文件: 1.pom.xml中添加依赖 <!-- 文件上传 -- ...