Traefik 2 基礎授權驗證(後篇)

Traefik 2 基礎授權驗證(後篇)
上篇文章中,我們提到了 Traefik 的 Forward Auth,本篇內容我們來展開聊聊如何使用它。

準備基礎的 Web 服務Demo
這篇文章裏,我們繼續使用 whoami 作爲 Web 服務,基礎的配置文件和上一篇文章中一致,暫時不需要額外的設置:

version: '3'

services:

  whoami:
    image: containous/whoami
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=traefik"

      - "traefik.http.routers.test-auth-web.middlewares=https-redirect@file"
      - "traefik.http.routers.test-auth-web.entrypoints=http"
      - "traefik.http.routers.test-auth-web.rule=Host(`whoami.lab.com`, `whoami.lab.io`)"

      - "traefik.http.routers.test-auth-ssl.entrypoints=https"
      - "traefik.http.routers.test-auth-ssl.tls=true"
      - "traefik.http.routers.test-auth-ssl.rule=Host(`whoami.lab.com`, `whoami.lab.io`)"

    networks:
      - traefik

networks:
  traefik:
    external: true

使用容器配置 Traefik Forward Auth 服務
thomseddon/traefik-forward-auth 這個開源項目讓我們在使用 Traefik 的時候,結合 Forward Auth 中間件,可以快速實現通用 OAuth / SSO 功能:

  • 支持多種驗證“服務商”:Google/ 通用OAuth / 通用OIDC
  • 支持自定義請求服務器和指定路徑,方便與現有系統集成
  • 支持基礎的用戶限制、授權來源限制、支持設置跨域 Cookie
    簡單來說,只要你的系統對外暴露服務是通過 Traefik,那麼可以非常輕鬆愉快的使用這個模式爲應用添加一層通用的前置 SSO 。可以達到效果類似我們在外部公網訪問公司內網服務時候,會出現的一個登陸框,只有登陸成功後,纔會展示我們想要看的內容。

使用這個方案的好處是,我們只需要結合一些簡單的膠水代碼,就可以做到背後的應用無修改接入或者幾乎無修改接入,即使應用本身不支持 OAuth / SSO 方式接入,或者說我們無法直接修改的商業付費軟件。

version: '3'

services:

  traefik-forward-auth:
    image: thomseddon/traefik-forward-auth:v2.2.0
    restart: always
    hostname: traefik-auth.lab.io
    environment:
      - LOG_LEVEL=trace
      - DEFAULT_PROVIDER=generic-oauth
      - PROVIDERS_GENERIC_OAUTH_AUTH_URL=https://sso.lab.io/dialog/authorize
      - PROVIDERS_GENERIC_OAUTH_TOKEN_URL=http://sso-web/oauth/token
      - PROVIDERS_GENERIC_OAUTH_USER_URL=http://sso-web/api/userinfo
      - PROVIDERS_GENERIC_OAUTH_USER_URL=http://sso-web/api/traefik-auth-user
      - PROVIDERS_GENERIC_OAUTH_CLIENT_ID=abc123
      - PROVIDERS_GENERIC_OAUTH_CLIENT_SECRET=ssh-secret
      - PROVIDERS_GENERIC_OAUTH_SCOPE=*
      - PROVIDERS_GENERIC_OAUTH_TOKEN_STYLE=header
      - SECRET=something-random
      - INSECURE_COOKIE=true
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=traefik"

      - "traefik.http.routers.traefik-auth-web.entrypoints=http"
      - "traefik.http.routers.traefik-auth-web.rule=Host(`traefik-auth.lab.com`, `traefik-auth.lab.io`)"

      - "traefik.http.routers.traefik-auth-ssl.entrypoints=https"
      - "traefik.http.routers.traefik-auth-ssl.rule=Host(`traefik-auth.lab.com`, `traefik-auth.lab.io`)"
      - "traefik.http.routers.traefik-auth-ssl.tls=true"

      - "traefik.http.middlewares.traefik-forward-auth.forwardauth.address=http://traefik-forward-auth:4181"
      - "traefik.http.middlewares.traefik-forward-auth.forwardauth.authResponseHeaders=X-Forwarded-User"
      - "traefik.http.services.traefik-forward-auth.loadbalancer.server.port=4181"
    networks:
      - traefik

networks:
  traefik:
    external: true

使用這個項目因爲配置項比較多,而顯得比較複雜,實際上並非如此,我們一點一點來理解它。

配置應用參數
我們在環境變量中定義了許多內容,這些內容的解釋可以參考官方文檔,這裏我選擇了 OAuth 作爲授權服務配置,爲了演示方便,我將他們運行在相同主機的相同容器網卡中,PROVIDERS_GENERIC_OAUTH_AUTH_URL 是用於用戶在瀏覽器前端訪問的地址,用於“確認授權”行爲,所以需要配置對外訪問的網絡域名,除此之外,PROVIDERS_GENERIC_OAUTH_TOKEN_URL、PROVIDERS_GENERIC_OAUTH_USER_URL、PROVIDERS_GENERIC_OAUTH_USER_URL 可以都走容器內部通信,更加高效。

如果我們的 SSO 服務可以進行獨立部署,那麼這裏四個 URL 變量需要都配置成可訪問的域名地址,如果使用 https 協議,涉及自簽名證書,需要重新構建容器。下一篇內容,我們再仔細展開 SSO 服務,這裏稍作了解,有個印象就行啦。


environment:
  - LOG_LEVEL=trace
  - DEFAULT_PROVIDER=generic-oauth
  - PROVIDERS_GENERIC_OAUTH_AUTH_URL=https://sso.lab.io/dialog/authorize
  - PROVIDERS_GENERIC_OAUTH_TOKEN_URL=http://sso-web/oauth/token
  - PROVIDERS_GENERIC_OAUTH_USER_URL=http://sso-web/api/userinfo
  - PROVIDERS_GENERIC_OAUTH_USER_URL=http://sso-web/api/traefik-auth-user
  - PROVIDERS_GENERIC_OAUTH_CLIENT_ID=abc123
  - PROVIDERS_GENERIC_OAUTH_CLIENT_SECRET=secret
  - PROVIDERS_GENERIC_OAUTH_SCOPE=*
  - PROVIDERS_GENERIC_OAUTH_TOKEN_STYLE=header
  - SECRET=something-random
  - INSECURE_COOKIE=true

接着我們來進行服務路由的配置。

配置應用服務路由
配置服務路由比較簡單,可以根據需求和喜好,設置是否“執行 HTTP 自動轉發 HTTPS”等邏輯,設置方法上一篇文章中有描述,就不再贅述:


labels:
  - "traefik.enable=true"
  - "traefik.docker.network=traefik"

  - "traefik.http.routers.traefik-auth-web.entrypoints=http"
  - "traefik.http.routers.traefik-auth-web.rule=Host(`traefik-auth.lab.com`, `traefik-auth.lab.io`)"

  - "traefik.http.routers.traefik-auth-ssl.entrypoints=https"
  - "traefik.http.routers.traefik-auth-ssl.tls=true"
  - "traefik.http.routers.traefik-auth-ssl.rule=Host(`traefik-auth.lab.com`, `traefik-auth.lab.io`)"
...

接着是配置 forwardauth 中間件,這裏和配置應用參數情況類似,因爲是同機部署演示,這裏使用應用名稱即可。如果是獨立部署,需要替換爲訪問域名:


labels:
  ...
  - "traefik.http.middlewares.traefik-forward-auth.forwardauth.address=http://traefik-forward-auth:4181"
  - "traefik.http.middlewares.traefik-forward-auth.forwardauth.authResponseHeaders=X-Forwarded-User"
  - "traefik.http.services.traefik-forward-auth.loadbalancer.server.port=4181"

上面的中間件配置中還存在一個 authResponseHeaders 配置項 :用來向後續服務傳遞通過鑑權的用戶信息,可以根據自己的需求進行修改或者移除。

最後,使用 docker-compose -d 啓動應用,等待應用啓動完畢,就可以準備應用接入啦。

完成應用配置

我們將文章開頭的 Web 服務 Demo 配置中添加一條簡單的配置規則,讓剛剛配置的 traefik-forward-auth 加入到應用服務路由中:


version: '3'

services:

  whoami:
    image: containous/whoami
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=traefik"
...
      - "traefik.http.routers.test-auth-ssl.middlewares=traefik-forward-auth@docker"

...
    networks:
      - traefik

networks:
  traefik:
    external: true

將內容單獨保存一個新的 docker-compose.yml ,再次繼續使用 docker-compose up -d 啓動服務,接着進行服務效果驗證。

驗證 Forward Auth SSO 效果
打開瀏覽器,輸入 whoami.lab.io ,可以看到首先是被重定向到了 https 協議,然後再次被重定向到了 sso.lab.io/... 的 SSO 鑑權地址,提示我們輸入賬號密碼。
Traefik 2 基礎授權驗證(後篇)

我們使用 curl 再來模擬一次服務端請求:

curl  https://whoami.lab.io -v    
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to whoami.lab.io (127.0.0.1) port 443 (#0)
...
> GET / HTTP/2
> Host: whoami.lab.io
> User-Agent: curl/7.64.1
> Accept: */*
> 
* Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
< HTTP/2 307 
< content-type: text/html; charset=utf-8
< date: Wed, 02 Dec 2020 13:45:35 GMT
< location: https://sso.lab.io/dialog/authorize?client_id=abc123&redirect_uri=https%3A%2F%2Fwhoami.lab.io%2F_oauth&response_type=code&scope=%2A&state=396bd5c20d6bcfdffc2426bddf619707%3Ageneric-oauth%3Ahttps%3A%2F%2Fwhoami.lab.io%2F
< set-cookie: _forward_auth_csrf=396bd5c20d6bcfdffc2426bddf619707; Path=/; Domain=whoami.lab.io; Expires=Thu, 03 Dec 2020 01:45:35 GMT; HttpOnly
< content-length: 271
< 
<a href="https://sso.lab.io/dialog/authorize?client_id=abc123&amp;redirect_uri=https%3A%2F%2Fwhoami.lab.io%2F_oauth&amp;response_type=code&amp;scope=%2A&amp;state=396bd5c20d6bcfdffc2426bddf619707%3Ageneric-oauth%3Ahttps%3A%2F%2Fwhoami.lab.io%2F">Temporary Redirect</a>.

* Connection #0 to host whoami.lab.io left intact
* Closing connection 0

可以看到配置依然是生效的,服務端返回了 307 重定向,我們發送到 whoami.lab.io 的請求被轉向到了 sso.lab.io ,符合我們的預期。

接着在瀏覽器中輸入賬號密碼,點擊提交,可以看到被重定向到了頁面授權確認頁面。

點擊允許,進行授權,等待授權完畢,我們就可以正式訪問到應用的頁面了。當然,也有一些應用會精簡掉用戶確認的對話框,讓驗證的整個流程更加的順滑:
Traefik 2 基礎授權驗證(後篇)

可以看到,應用請求頭 X-Forwarded-User 和 Cookie 中可以看到通過授權的用戶信息,可以進行進一步處理,或者鑑權規則的完善。

最後
寫到這裏,Traefik 基礎鑑權驗證的內容就完畢了,但是 SSO / OAuth 相關的內容纔剛剛開始。

--EOF

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章