IdentityServer 部署踩坑記

IdentityServer 部署踩坑記

Intro

周末終于部署了 IdentityServer 以及 IdentityServerAdmin 項(xiàng)目,踩了幾個(gè)坑,在此記錄分享一下。

部署架構(gòu)

項(xiàng)目是基于 IdentityServerAdmin 項(xiàng)目修改的,感謝作者的開(kāi)源付出,有需要 IdentityServer 管理需求的可以關(guān)注一下,覺(jué)得好用的可以給個(gè) star 支持一下 https://github.com/skoruba/IdentityServer4.Admin

實(shí)際部署的有兩個(gè)服務(wù),一個(gè)是 IdentityServer 項(xiàng)目(https://id.weihanli.xyz),一個(gè)是 IdentityAdmin 項(xiàng)目(<https://id-admin.weihanli.xyz>)。

兩個(gè)服務(wù)都是部署在一臺(tái)服務(wù)器上,這一臺(tái)服務(wù)器上部署一個(gè)單節(jié)點(diǎn)的 kubernetes,兩個(gè)服務(wù)都是部署在 k8s 上并通過(guò) NortPort 的方式對(duì)外提供服務(wù),外面有一層 nginx 做了請(qǐng)求轉(zhuǎn)發(fā)同時(shí)提供對(duì)外 https 的支持。

image-20200407151639076

最初的 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重定向到內(nèi)網(wǎng)地址

部署起來(lái)之后,IdentityServer 可以訪問(wèn),但是 IdentityAdmin 訪問(wèn)的時(shí)候會(huì)重定向到 IdentityServer 去登錄,在發(fā)生重定向的時(shí)候會(huì)重定向到內(nèi)網(wǎng)地址,重定向到了 172.17.0.1:31210 這個(gè)內(nèi)網(wǎng)地址,這個(gè)地址是一個(gè)內(nèi)網(wǎng)地址,公網(wǎng)肯定是沒(méi)有辦法訪問(wèn)的,在網(wǎng)上 Google 了半天發(fā)現(xiàn)有個(gè)類似的問(wèn)題 網(wǎng)絡(luò)回流(NAT Loopback/ Hairpin NAT),大概就是在同一網(wǎng)段的內(nèi)網(wǎng)中的兩個(gè)服務(wù)通信的時(shí)候通過(guò)公網(wǎng)域名沒(méi)有辦法訪問(wèn),會(huì)轉(zhuǎn)換成內(nèi)網(wǎng)IP訪問(wèn),所以發(fā)生重定向的時(shí)候會(huì)出現(xiàn)原本是域名重定向但是卻變成了內(nèi)網(wǎng)IP(不確定我的這種情況是不是屬于網(wǎng)絡(luò)回流的情況,有網(wǎng)絡(luò)大佬的話可以幫忙分析一下,萬(wàn)分感謝)

因?yàn)槭褂昧?nginx 并且轉(zhuǎn)發(fā)后的內(nèi)網(wǎng) IP 地址是 nginx 轉(zhuǎn)發(fā)到的請(qǐng)求地址,所以又 Google 了 nginx proxy redirect 關(guān)鍵詞,最后找到一個(gè)解決方案 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;
     }
}

增加了上面的配置之后再發(fā)生重定向的時(shí)候地址就是正確的了,不再是一個(gè)內(nèi)網(wǎng)IP 了

Invalid Token

Identity Server 重定向的問(wèn)題解決之后,馬上就出現(xiàn)了新的問(wèn)題。。。

首先在 Identity Server 登錄成功之后返回到 IdentityAdmin 的時(shí)候會(huì)報(bào)錯(cuò),查看日志可以看到是 token 不合法的問(wèn)題,起初是 issuer 不對(duì)的問(wèn)題,我想可能是 issuer 可能 http/https 不一致的問(wèn)題,于是增加了一個(gè)配置,直接在注冊(cè) IdentityServer 的時(shí)候使用指定的 issuer ,想著這樣就不會(huì)有 http/https 的問(wèn)題,于是重新部署,重新嘗試之后,token 還是有問(wèn)題,日志顯示是token 簽名驗(yàn)證錯(cuò)誤,這時(shí)不經(jīng)意之間看了一眼 IdentityServer 的 發(fā)現(xiàn)文檔,打開(kāi)之后發(fā)現(xiàn)里面的各種 endpoint 都是 http 的,后來(lái)發(fā)現(xiàn) IdentityServer 有一個(gè) PublicOrigin 的配置,把這個(gè)配置配置成 https://id.weihanli.xyz 之后就沒(méi)有 invalid token 之類的錯(cuò)誤了,再看發(fā)現(xiàn)文檔的時(shí)候,endpoint 也是基于 https 的了。

Identity-Admin 502

IdentityServer 登錄成功之后重定向到 IdentityAdmin 的時(shí)候 502,但是服務(wù)是存在的 在日志里只找到下面這樣的錯(cuò)誤日志

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

在網(wǎng)上 Google 之后找到了這個(gè)issue: https://github.com/IdentityServer/IdentityServer4/issues/1670,嘗試了下面這個(gè)解決方案解決了,是因?yàn)橹囟ㄏ虻臅r(shí)候請(qǐng)求信息太大了

nginx 中 IdentityAdmin 項(xiàng)目增加配置:

proxy_buffer_size          128k;

proxy_buffers              4 256k;

proxy_busy_buffers_size    256k;

修改之后,執(zhí)行 sudo nginx -s reload 重新加載配置之后就正常了

More

最后現(xiàn)在在用的有效的完整的 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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容