Buy Me a Coffee

桌面App也能玩單一登入?開源SSO大戰K8s,一篇搞懂!


哈囉各位鍵盤俠們!今天我們要來聊一個超級有趣的話題 - 如何讓你的桌面應用程式也能享受單一登入(SSO)的便利!不僅如此,我們還要看看這些SSO解決方案如何在Kubernetes(K8s)上大顯身手,甚至與Azure Entra打成一片。準備好了嗎?繫好安全帶,我們要起飛啦!

sequenceDiagram
    actor User
    participant Desktop App
    participant OpenSource SSO
    participant JWT Issuer
    participant Azure Entra
    participant Kubernetes Backend

    User->>Desktop App: 1. 嘗試登入
    Desktop App->>OpenSource SSO: 2. 請求認證
    OpenSource SSO->>Azure Entra: 3. 轉發認證請求
    Azure Entra->>User: 4. 提示登入
    User->>Azure Entra: 5. 輸入憑證
    Azure Entra->>OpenSource SSO: 6. 返回認證結果
    OpenSource SSO->>JWT Issuer: 7. 請求 JWT
    JWT Issuer->>OpenSource SSO: 8. 返回 JWT
    OpenSource SSO->>Desktop App: 9. 發放 JWT
    Desktop App->>Kubernetes Backend: 10. 使用 JWT 訪問資源
    Kubernetes Backend->>JWT Issuer: 11. 驗證 JWT
    JWT Issuer->>Kubernetes Backend: 12. 確認 JWT 有效
    Kubernetes Backend->>Desktop App: 13. 返回請求資源
    Desktop App->>User: 14. 顯示結果

    Note over OpenSource SSO: Keycloak, Authelia, Dex, 或 OpenUnison
    Note over JWT Issuer: 專門的 JWT 簽發和驗證服務

1. 單一登入?聽起來就是個帥氣的名詞!

首先,讓我們來聊聊什麼是單一登入(SSO)。想像一下,你有一把神奇的鑰匙,可以開啟所有的門。不用再為了記住一堆密碼而頭痛,也不用每次進出不同的房間都要掏出一把新鑰匙。這就是SSO的魔力!一次登入,暢通無阻。聽起來很酷吧?

但是,當我們談到桌面應用程式時,事情就變得有趣了。畢竟,我們的老朋友桌面App可不像網頁那樣容易玩轉SSO。不過別擔心,本文就是要帶你一探究竟,看看如何讓桌面App也能加入SSO的狂歡派對!

2. 開源SSO解決方案:自由的風在吹

在開始我們的冒險之前,先來認識幾個厲害的開源SSO解決方案吧!這些傢伙不僅功能強大,還能在Kubernetes上運行,簡直就是現代應用架構的最佳拍檔!

2.1 Keycloak: 身份認證界的超級英雄

Keycloak就像是復仇者聯盟中的鋼鐵人,功能強大又靈活。它支援SAML、OAuth 2.0和OpenID Connect等協議,簡直就是全能選手。更棒的是,它可以輕鬆部署在Kubernetes上,用容器映像或運算子都行。

2.2 Authelia: 輕量級的認證高手

如果說Keycloak是鋼鐵人,那Authelia就是蜘蛛人 - 輕巧靈活,但同樣強大。它特別適合那些想要簡單SSO系統的組織,支援會話cookie和OpenID Connect,完全能滿足你的需求。

2.3 Dex: Kubernetes的好朋友

Dex就像是為Kubernetes量身打造的美國隊長。它是一個OpenID Connect身份提供者,可以與各種連接器(如LDAP和SAML)合作無間。如果你的團隊正在使用Kubernetes,Dex絕對是你不能錯過的選擇。

2.4 OpenUnison: Kubernetes認證的終極武器

OpenUnison就像是黑寡婦,專門為Kubernetes環境設計的SSO和認證平台。它不僅可以簡化Kubernetes儀表板的訪問,還支援跨平台的kubectl SSO。簡直是Kubernetes世界中的多面手!

3. 讓桌面App與SSO共舞:這不是魔法,是技術!

現在,讓我們來到最刺激的部分 - 如何讓你的桌面應用程式與這些SSO解決方案完美結合?別擔心,雖然聽起來很複雜,但我們會一步一步來,保證讓你的桌面App成為SSO派對的座上賓!

3.1 選擇你的武器:認證協議

首先,你需要選擇一個認證協議。大多數SSO系統都支援OAuth 2.0和OpenID Connect(OIDC)。對於桌面應用程式來說,OAuth 2.0的授權碼流程是個不錯的選擇。聽起來很專業對吧?別怕,讓我用簡單的話解釋一下:

  1. 你的App打開瀏覽器,把用戶帶到SSO登入頁面。
  2. 用戶登入成功後,SSO服務器會把用戶帶回你的App,還會給你一個神奇的授權碼。
  3. 你的App拿著這個授權碼,偷偷地跟SSO服務器說悄悄話,換取一個訪問令牌。
  4. 有了這個訪問令牌,你的App就可以自由自在地訪問API了!

是不是感覺像是在玩間諜遊戲?沒錯,就是這麼刺激!

3.2 與SSO系統牽手成功

接下來,我們需要設置SSO系統,讓它認識你的桌面App。這就像是在社交網絡上加好友,只不過更正式一點。

# Keycloak Client Configuration Example
clients:
  - clientId: my-desktop-app
    name: My Desktop Application
    enabled: true
    clientAuthenticatorType: client-secret
    secret: "your-client-secret"
    redirectUris:
      - "http://localhost:8000/callback"
    webOrigins:
      - "+"
    protocol: openid-connect
    attributes:
      pkce.code.challenge.method: S256
    protocolMappers:
      - name: audience
        protocol: openid-connect
        protocolMapper: oidc-audience-mapper
        consentRequired: false
        config:
          included.client.audience: account
          id.token.claim: "true"
          access.token.claim: "true"

上面的例子展示了如何在Keycloak中設置你的桌面應用程式作為客戶端。看起來很複雜?別擔心,讓我來解釋一下關鍵點:

  • clientId: 這就是你的App的獨特ID,就像是它的身份證號碼。
  • redirectUris: 這是告訴SSO系統,用戶登入成功後應該被帶到哪裡。
  • secret: 這是你的App和SSO系統之間的小秘密,千萬不要告訴別人哦!
  • protocol: 這裡我們用的是OpenID Connect,它是基於OAuth 2.0的。

設置好這些,你的App就成功加入SSO的朋友圈啦!

3.3 在桌面App中實現授權

現在,我們需要讓你的桌面App學會如何和SSO系統打交道。這就像是教你的App說一種新語言。具體怎麼做,要看你用什麼程式語言開發的App:

  • 如果你用C#/.NET,可以試試IdentityModel.OidcClient。
  • Java開發者可以使用Spring Security OAuth。
  • 如果你是Electron/Node.js的粉絲,openid-client會是個好選擇。
// C# Example using IdentityModel.OidcClient
using IdentityModel.OidcClient;

var options = new OidcClientOptions
{
    Authority = "https://your-sso-server.com",
    ClientId = "my-desktop-app",
    ClientSecret = "your-client-secret",
    RedirectUri = "http://localhost:8000/callback",
    Scope = "openid profile email",
    FilterClaims = false,
    Browser = new SystemBrowser(8000)
};

var client = new OidcClient(options);
var result = await client.LoginAsync();

if (result.IsError)
{
    Console.WriteLine($"Error: {result.Error}");
    return;
}

Console.WriteLine($"Access Token: {result.AccessToken}");

這個例子展示了如何在C#桌面應用程式中實現SSO登入。主要步驟包括:

  1. 設置OidcClientOptions,包括SSO服務器地址、客戶端ID和密鑰等。
  2. 創建OidcClient實例。
  3. 調用LoginAsync()方法進行登入。
  4. 處理登入結果,獲取訪問令牌。

看,其實沒那麼可怕吧?只要幾行代碼,你的桌面App就能成功加入SSO的世界了!

3.4 令牌管理:別讓你的鑰匙過期了!

獲得訪問令牌後,我們還需要好好管理它。畢竟,令牌也是會過期的,就像是魔法公主的魔法,到了午夜就會消失。

  • 處理令牌過期:大多數OAuth 2.0訪問令牌的壽命都不長。你的App需要學會在令牌過期前,使用刷新令牌來獲取新的訪問令牌。
  • 實現登出:記得要讓用戶能夠安全地登出,這意味著要撤銷令牌或在SSO提供者那裡使會話無效。

4. Kubernetes:SSO的新戰場

現在,讓我們把目光投向雲端,看看這些SSO解決方案如何在Kubernetes上大顯身手。

4.1 為什麼要在K8s上運行SSO?

簡單來說,就是為了讓你的身份認證系統更具彈性和可擴展性。想像一下,你的SSO系統就像是一個超級英雄,而Kubernetes就是它的高科技戰衣,讓它能夠應對各種挑戰。

4.2 在K8s上部署SSO:就像搭積木一樣簡單

以Keycloak為例,你可以使用Helm圖表或運算子來部署它。這就像是用樂高積木搭建一個複雜的城堡,只不過這個城堡可以保護你所有的應用程式!

# Keycloak Deployment in Kubernetes
apiVersion: apps/v1
kind: Deployment
metadata:
  name: keycloak
  labels:
    app: keycloak
spec:
  replicas: 1
  selector:
    matchLabels:
      app: keycloak
  template:
    metadata:
      labels:
        app: keycloak
    spec:
      containers:
      - name: keycloak
        image: quay.io/keycloak/keycloak:latest
        args: ["start-dev"]
        env:
        - name: KEYCLOAK_ADMIN
          value: "admin"
        - name: KEYCLOAK_ADMIN_PASSWORD
          value: "admin"
        - name: KC_PROXY
          value: "edge"
        ports:
        - name: http
          containerPort: 8080
        readinessProbe:
          httpGet:
            path: /realms/master
            port: 8080

這個YAML文件描述了如何在Kubernetes中部署Keycloak。主要包括:

  • 使用最新的Keycloak鏡像
  • 設置管理員帳號和密碼
  • 配置代理設置
  • 設置容器端口和健康檢查

就是這麼簡單!有了這個配置,你的Keycloak就能在Kubernetes集群中愉快地奔跑了。

5. Azure Entra:雲端身份認證的新寵

說到雲端身份認證,我們不得不提到Microsoft的Azure Entra(前身是Azure Active Directory)。它就像是雲端世界的超級明星,幾乎所有人都想和它合作。那麼,

好的,讓我們繼續探討Azure Entra與開源SSO解決方案的完美結合。

那麼,我們剛才介紹的這些開源SSO解決方案如何與Azure Entra這個大明星合作呢?別擔心,它們可以成為最佳拍檔!

5.1 Keycloak 與 Azure Entra: 強強聯手

想像Keycloak是一個多才多藝的演員,而Azure Entra是一個超級經紀人。這兩個強者聯手,簡直就是娛樂圈的dream team!

如何實現:

  1. 在Keycloak中將Azure Entra設置為身份提供者。
  2. 配置Azure Entra的客戶端憑證(client ID, secret等)。
  3. 設置OpenID Connect端點。

這樣,用戶就可以使用Azure Entra賬號登入,而Keycloak負責管理認證會話和用戶資料。簡直是天作之合!

5.2 Authelia: 與Azure Entra的完美舞步

Authelia雖然體型輕巧,但舞步可不輸人。它可以通過OpenID Connect與Azure Entra完美配合,就像是一對默契十足的舞伴。

設置步驟:

  1. 在Authelia中配置Azure Entra作為OpenID Connect提供者。
  2. 設置適當的客戶端ID和密鑰。
  3. 配置正確的Azure Entra端點。

這樣,Authelia就成為了連接你的應用和Azure Entra的橋樑,讓認證過程如絲般順滑。

5.3 Dex: 為Kubernetes搭建Azure Entra之橋

Dex就像是一個翻譯官,能夠讓Kubernetes和Azure Entra順暢對話。它支持多種身份連接器,當然包括Azure Entra。

整合方法:

  1. 在Dex中配置Azure Entra作為OpenID Connect提供者。
  2. 設置適當的客戶端憑證和Azure Entra端點。
  3. 配置Dex作為Kubernetes的認證代理。

這樣,你的Kubernetes集群就能使用Azure Entra進行身份認證,簡直是雲原生應用的福音!

5.4 OpenUnison: 天生就是為了Azure Entra

OpenUnison對Azure Entra的支持簡直就是與生俱來。它不僅可以讓用戶使用Azure Entra憑證登入,還能利用Azure群組來管理Kubernetes的角色based訪問控制(RBAC)。

設置步驟:

  1. 在OpenUnison中配置Azure Entra作為OpenID Connect提供者。
  2. 設置適當的客戶端憑證和端點。
  3. 配置Azure群組與Kubernetes RBAC的映射關係。

有了OpenUnison,管理Kubernetes集群的訪問權限就變得輕而易舉,簡直是DevOps團隊的福音!

6. 實戰案例: 桌面App的SSO之旅

好了,理論知識我們已經掌握得差不多了。現在,讓我們通過一個實際案例,看看如何將所有這些知識綜合起來,為一個桌面應用程式實現SSO。

6.1 案例背景

假設我們有一個名為"超級筆記"的桌面應用程式,它是用Electron開發的。我們想要為它添加SSO功能,讓用戶可以使用他們的Azure Entra賬號登入。同時,我們的後端服務運行在Kubernetes集群上,也需要進行身份認證。

6.2 技術選型

經過慎重考慮,我們決定:

  • 使用Keycloak作為SSO解決方案
  • 在Kubernetes上部署Keycloak
  • 將Azure Entra配置為Keycloak的身份提供者

6.3 實現步驟

讓我們一步一步來實現這個SSO夢想吧!

步驟1: 在Kubernetes上部署Keycloak

首先,我們需要在Kubernetes集群上部署Keycloak。我們可以使用Helm chart來簡化這個過程。

# Add Keycloak Helm repository
helm repo add bitnami https://charts.bitnami.com/bitnami

# Update Helm repositories
helm repo update

# Install Keycloak
helm install my-keycloak bitnami/keycloak \
  --set auth.adminUser=admin \
  --set auth.adminPassword=adminpassword \
  --set service.type=LoadBalancer

這個腳本會在你的Kubernetes集群上安裝Keycloak,並設置一個管理員賬號。注意,在生產環境中,你應該使用更安全的方式來管理密碼,比如使用Kubernetes的Secrets。

步驟2: 配置Azure Entra作為Keycloak的身份提供者

接下來,我們需要在Keycloak中配置Azure Entra作為身份提供者。這個過程需要在Keycloak的管理控制台中完成。

  1. 登入Keycloak管理控制台
  2. 選擇你的realm (如果沒有,先創建一個)
  3. 在左側菜單中,點擊"Identity Providers"
  4. 點擊"Add provider"並選擇"OpenID Connect v1.0"
  5. 填寫以下信息:

記得將{tenant-id}替換為你的Azure Entra租戶ID。

步驟3: 配置桌面應用程式

現在,我們需要配置我們的"超級筆記"應用程式來使用Keycloak進行身份認證。

const { app, BrowserWindow } = require('electron');
const { ElectronAuth } = require('@getinsomnia/electron-oauth-helper');

const auth = new ElectronAuth('keycloak', {
  clientId: 'super-notes-app',
  authorizationUrl: 'https://your-keycloak-url/auth/realms/your-realm/protocol/openid-connect/auth',
  tokenUrl: 'https://your-keycloak-url/auth/realms/your-realm/protocol/openid-connect/token',
  useBasicAuthorizationHeader: true,
  redirectUri: 'http://localhost/callback',
});

async function createWindow() {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,
    },
  });

  try {
    const token = await auth.getToken();
    console.log('Access Token:', token.access_token);
    // 使用token進行後續操作...
  } catch (error) {
    console.error('Authentication failed:', error);
  }

  win.loadFile('index.html');
}

app.whenReady().then(createWindow);

這個示例展示了如何在Electron應用中實現OpenID Connect認證。它使用了@getinsomnia/electron-oauth-helper庫來簡化OAuth流程。

記得替換your-keycloak-urlyour-realm為你的實際Keycloak URL和realm名稱。

步驟4: 配置後端服務

最後,我們需要配置運行在Kubernetes上的後端服務,讓它能夠驗證從桌面應用發來的token。這通常涉及到在你的API服務中添加一個中間件來驗證JWT token。

const express = require('express');
const jwt = require('express-jwt');
const jwksRsa = require('jwks-rsa');

const app = express();

const checkJwt = jwt({
  secret: jwksRsa.expressJwtSecret({
    cache: true,
    rateLimit: true,
    jwksRequestsPerMinute: 5,
    jwksUri: `https://your-keycloak-url/auth/realms/your-realm/protocol/openid-connect/certs`
  }),
  audience: 'account',
  issuer: `https://your-keycloak-url/auth/realms/your-realm`,
  algorithms: ['RS256']
});

app.use(checkJwt);

app.get('/api/protected', function(req, res) {
  res.json({ message: 'This is a protected endpoint!' });
});

app.listen(3000);

這個示例展示了如何使用express-jwtjwks-rsa庫來驗證JWT token。記得替換your-keycloak-urlyour-realm為你的實際Keycloak URL和realm名稱。

7. 結語: SSO,讓身份認證不再是惡夢

我們的旅程到這裡就要告一段落了。讓我們回顧一下我們學到了什麼:

  1. 我們了解了幾個強大的開源SSO解決方案: Keycloak, Authelia, Dex和OpenUnison。
  2. 我們學會了如何讓桌面應用程式加入SSO的狂歡派對。
  3. 我們探索了如何在Kubernetes上部署和運行這些SSO解決方案。
  4. 我們還看到了如何將這些解決方案與Azure Entra完美結合。
  5. 最後,我們通過一個實際案例,將所有這些知識綜合起來,實現了一個完整的SSO方案。

記住,實現SSO並不是一蹴而就的事情。它需要仔細的規劃、配置和測試。但是,一旦你成功實現了SSO,你就會發現它帶來的便利遠遠超過了實現它所付出的努力。

無論你是在開發桌面應用、Web應用還是管理大型的Kubernetes集群,SSO都能為你的用戶帶來更流暢、更安全的體驗。所以,勇敢地踏上SSO之旅吧,讓身份認證不再是你和你用戶的噩夢!

最後,別忘了:在身份認證的世界裡,安全永遠是第一位的。定期更新你的SSO配置,關注最新的安全最佳實踐,讓你的應用在SSO的護盾下安全無憂。

好了,各位SSO冒險家們,你們準備好接受挑戰了嗎?讓我們一起,讓身份認證變得簡單、安全、順暢吧!🚀🔐