你可能想要整合一個 Discourse 論壇?使用 Authing SSO 零程式碼幫你實現單點登入

willin 發表於 2022-01-15

Authing 是什麼?

Authing 是國內首款以開發者為中心的全場景身份雲產品,整合了所有主流身份認證協議,為企業和開發者提供完善安全的使用者認證和訪問管理服務。

以「API First」作為產品基石,把身份領域所有常用功能都進行了模組化的封裝,通過全場景程式語言 SDK 將所有能力 API 化提供給開發者。同時,使用者可以靈活的使用 Authing 開放的 RESTful APIs 進行功能擴充,滿足不同企業不同業務場景下的身份管理需求。

傳統系統 SSO 單點登入改造

首先,需要對原有系統的使用者體系進行改造,使其能夠適應通用的使用者認證標準協議(如 OAuth)。如果系統體量較大,甚至還需要考慮將原有業務中的使用者體系抽出,專門做成單點登入的使用者中心。需要進行設計、編碼、測試、升級、擴容等一系列複雜的開發運維操作,才能夠實現。

該方式耗時間,耗精力,耗成本,風險大(需要在業務領域之外不斷去踩坑)。

Authing SSO 整合

如果您的應用是基於 Authing 提供的身份系統進行開發,那麼恭喜你,可以使用較少的程式碼(或者配置)即可輕鬆幾步,快速完成單點登入的整合。

該方式低成本,無須額外設計和開發,採用標準協議,輕鬆打通。

Discourse 安裝

參考資料:

建議將 Discourse Docker 倉庫 Fork,並在本地先進行開發除錯確認無誤後再進行產品環境的安裝。下面是簡單的安裝步驟說明及配置中常見問題的 FAQ。

注意:請在 Linux 伺服器或者 macOS 下進行安裝(Windows 需要自行摸索一下)。

拉取 Discourse Docker 倉庫

git clone https://github.com/discourse/discourse_docker.git /var/discourse
cd /var/discourse

使用自動化配置指令碼:

./discourse-setup

root 使用者的話,需要在前面加 sudo 執行。根據提示一步一步輸入配置項,完成安裝配置。預設的配置在本地執行的時候大概率會執行不起來。

開啟 containers/app.yml 配置檔案進行配置調整,如果手動配置,也可以執行:

cp samples/standalone.yml containers/app.yml

複製一個示例模板作為開始。

應用配置

在開始配置之前,先確保域名已經繫結到伺服器上(DNS 中的 A 記錄繫結),或者本地修改 /etc/hosts 檔案(不要使用 example.com 或者需要強制 https 的域名字尾作為本地開發除錯,如: .app.dev等)。

環境變數設定參考:

env:
  LC_ALL: en_US.UTF-8
  LANG: en_US.UTF-8
  LANGUAGE: en_US.UTF-8
  EMBER_CLI_PROD_ASSETS: 1
  # DISCOURSE_DEFAULT_LOCALE: en

  ## How many concurrent web requests are supported? Depends on memory and CPU cores.
  ## will be set automatically by bootstrap based on detected CPUs, or you can override
  #UNICORN_WORKERS: 3

  ## TODO: The domain name this Discourse instance will respond to
  ## Required. Discourse will not work with a bare IP number.
  DISCOURSE_HOSTNAME: 'discourse.local'

  ## Uncomment if you want the container to be started with the same
  ## hostname (-h option) as specified above (default "$hostname-$config")
  # DOCKER_USE_HOSTNAME: true

  ## TODO: List of comma delimited emails that will be made admin and developer
  ## on initial signup example '[email protected],[email protected]'
  DISCOURSE_DEVELOPER_EMAILS: '[email protected]'

  ## TODO: The SMTP mail server used to validate new accounts and send notifications
  # SMTP ADDRESS, username, and password are required
  # WARNING the char '#' in SMTP password can cause problems!
  DISCOURSE_SMTP_ADDRESS: smtp.mail.qq.com
  DISCOURSE_SMTP_PORT: 25
  DISCOURSE_SMTP_USER_NAME: [email protected]
  DISCOURSE_SMTP_PASSWORD: "password"
  DISCOURSE_SMTP_ENABLE_START_TLS: fales       # (optional, default true)
  DISCOURSE_SMTP_AUTHENTICATION: plain
  DISCOURSE_SMTP_OPENSSL_VERIFY_MODE: none

  DISCOURSE_NOTIFICATION_EMAIL: [email protected]

  ## If you added the Lets Encrypt template, uncomment below to get a free SSL certificate
  #LETSENCRYPT_ACCOUNT_EMAIL: [email protected]
  ## The http or https CDN address for this Discourse instance (configured to pull)
  ## see https://meta.discourse.org/t/14857 for details
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com
  ## The maxmind geolocation IP address key for IP address lookup
  ## see https://meta.discourse.org/t/-/137387/23 for details
  #DISCOURSE_MAXMIND_LICENSE_KEY: 1234567890123456

簡單說明:

  • UNICORN_WORKERS:根據 CPU 數量決定 Worker 數量或者手動配置
  • DISCOURSE_HOSTNAME:正確配置域名
  • DISCOURSE_SMTP_XXX:正確配置 SMTP 郵件傳送服務,不然會收不到驗證碼和通知郵件

外掛配置:

## Plugins go here
## see https://meta.discourse.org/t/19157 for details
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git
          - git clone https://github.com/discourse/discourse-oauth2-basic.git
          - git clone https://github.com/angelim/discourse_user_auto_activation.git

這三個外掛的作用:

  • Docker 管理,自帶預設
  • OAuth 2 整合,用於與 Authing SSO 連線實現單點登入
  • 自動啟用(郵箱)外掛,可選

啟動論壇服務

提醒:先配置好 SSL 證書再啟動服務(參考 FAQ SSL 證書配置,或者使用 Let's Encrypt 簽發證書)。

配置完成後製作映象:

./launcher bootstrap app
./launcher start app

如果已經初始化過,可以通過重新制作映象的方式:

./launcher rebuild app

過程漫長,耐心等待。下面整理了我在除錯過程中遇到的一些問題和一些提示。

FAQ

域名配置

主要修改模板:

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Uncomment these two lines if you wish to add Lets Encrypt (https)
  - "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"
  • 如果需要 SSL 支援, "templates/web.ssl.template.yml" 這個模板檔案需要引入。
  • 如果需要免費的域名證書更新, "templates/web.letsencrypt.ssl.template.yml" 這個模板需要引入。

同時根據需要,將埠開放出來:

## which TCP/IP ports should this container expose?
## If you want Discourse to share a port with another webserver like Apache or nginx,
## see https://meta.discourse.org/t/17247 for details
expose:
  - "80:80"   # http
  - "443:443" # https

SSL 證書配置

首先確認一下檔案目錄的對映是否正確:

## The Docker container is stateless; all data is stored in /shared
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/log/var-log
      guest: /var/log

類似這樣的目錄對映,將證書檔案放置到對應的 ssl 目錄下,檢查這兩個檔案路徑是否正確:

/var/discourse/shared/standalone/ssl/ssl.crt
/var/discourse/shared/standalone/ssl/ssl.key

自簽證書參考:

openssl genrsa -aes256 -passout pass:gsahdg -out ssl.pass.key 4096
openssl rsa -passin pass:gsahdg -in ssl.pass.key -out ssl.key  
openssl req -new -key ssl.key -out ssl.csr             

# You are about to be asked to enter information that will be incorporated
# into your certificate request.
# What you are about to enter is what is called a Distinguished Name or a DN.
# There are quite a few fields but you can leave some blank
# For some fields there will be a default value,
# If you enter '.', the field will be left blank.
# -----
# Country Name (2 letter code) []:CN
# State or Province Name (full name) []:Jiangsu
# Locality Name (eg, city) []:Nanjing
# Organization Name (eg, company) []:Xibang Tech
# Organizational Unit Name (eg, section) []:
# Common Name (eg, fully qualified host name) []:discourse.local
# Email Address []:[email protected]

# Please enter the following 'extra' attributes
# to be sent with your certificate request
# A challenge password []:      
openssl x509 -req -sha256 -days 365 -in ssl.csr -signkey ssl.key -out ssl.crt

自簽證書需要信任,在 macOS 下就是雙擊開啟 .crt 檔案,選擇信任始終信任,過程中需要輸入兩次密碼即可。

禁用 SSL

該步驟並非必要,如果懶得配置 SSL 本地自簽名證書(比如我),可以將原有的配置考出,把 SSL 部分給註釋掉。

# 先將配置從映象拷貝出來
docker cp app:/etc/nginx/conf.d/discourse.conf ./discourse.conf
# 修改配置後執行
docker cp ./discourse.conf app:/etc/nginx/conf.d/discourse.conf 
docker exec app nginx -s reload

其中主要修改的部分為,將 https 請求跳回 http:

# attempt to preserve the proto, must be in http context
map $http_x_forwarded_proto $thescheme {
  default $scheme;
  https http;
}

將 80 跳轉到 443 的邏輯刪除:

server {
  listen 80;
  # 將跳轉的部分刪除,並與 listen 443 的 `server` 合併
}

Build 或啟動失敗

失敗原因:執行 git clone 命令之後出錯,該情況出現在國內伺服器拉取映象。可以在碼雲或者其他國內 Git 服務商上匯入 Github 的倉庫,然後用國內映象地址。

失敗原因:域名無法訪問,檢查配置或本地 HOSTS,是否已經繫結好域名。

失敗原因:啟動成功但無法訪問,一般僅在本地除錯時出現,域名雖然是可以隨意起,但要注意規則(比如沒有配置 SSL 證書 nginx-error 日誌會有,比如 .dev 域名我在本地測試時使用自籤 SSL 證書就始終無法訪問但 nginx-access 日誌卻顯示正常)。

訪問論壇並進行初始化配置

訪問 localhost 或者你配置的域名,註冊管理員使用者並進行初始化配置。

在這裡插入圖片描述

通過郵件驗證連結重新進入後,開始初始化配置。11 個步驟設定完後,進入管理後臺-設定。

左側邊欄選擇【登入】

在這裡插入圖片描述

關閉本地登入(建議穩妥起見,在單點登入配置完成後關閉也可以)。

進入外掛設定:

在這裡插入圖片描述

點選設定後停留在當前配置頁面(稍後繼續設定)。在新視窗中開啟 Authing 控制檯。

Authing SSO 單點登入整合

在單點登入 SSO 應用市場中搜尋 Discourse。點選獲取應用進入配置。

在這裡插入圖片描述

第一步是填寫論壇名稱,第二步進行登入配置。

在這裡插入圖片描述

只需要填入一個 Redirect URI (注意一下這裡是區分 http / https 的,如果不對就會報 redirect_uri_mismatch 錯誤),其他配置項對應複製填入到 Discourse 外掛配置中。示例: http://discourse.local/auth/oauth2_basic/callback (替換你的域名,後邊路徑保持一致)。

在這裡插入圖片描述

另外還需要配置的專案為:

  • oauth2 json user id path: 填入 sub
  • oauth2 json username path:填入 nickname 或者 username
  • oauth2 json name path:填入 name
  • oauth2 json email path:填入 email
  • oauth2 json email verified path: 填入 email_verified
  • oauth2 json avatar path:填入 picture
  • oauth2 send auth header 在 HTTP 授權標頭中傳送客戶端憑據:取消勾選

儲存外掛配置。

在這裡插入圖片描述

儲存訪問授權之後,可以在新的隱私視窗測試一下。

在這裡插入圖片描述

自動將 Authing 使用者資訊帶入論壇。測試成功。

同時管理員賬戶(郵箱與 Authing 使用者相同)即可無縫銜接至 Authing SSO 單點登入方式。

至此完成,大功告成。

延伸

通過 Authing SSO 還可以通過無程式碼的方式接入:

  • 協同工具:如禪道、ProcessOn、石墨文件、Notion、Tower、Teambition、飛書、Confluence 等
  • 雲端計算資源:如阿里雲、騰訊雲、AWS、百度智慧雲、金山雲、華為雲等
  • 開發者工具:如 Gitlab、Jira、Coding.net、Bitbucket、Jenkins 等
  • (目前應用商店裡提供)其他共計 120 種服務/平臺/軟體

同時還可以以低程式碼/零程式碼的形式,接入各類系統、軟體,目前支援的自建應用支援的協議有:

  • OAuth 2.0
  • SAML 2
  • CAS

使用 Authing SSO,可以輕鬆整合 NodeBB 論壇、Wordpress 站點等等等等……的單點登入。