Try   HackMD
tags: keycloak Tool

五、Keycloak串接Google Auth設置與Demo Code

在前面的章節中,我們詳細探討了Keycloak的基礎知識,這一Part稍微講一下如何實際運用Keycloak,結合OAuth 2.0協議,來實現Google認證登入,達成單點登入(SSO)的功能。我們的Demo會如下圖Flow,實作一個簡易的Web API,當使用Web API時,第一時間會打到Keycloak,再由Keycloak導到Google認證頁面,認證過後瀏覽器才會收到正確的API資料。基本上會有三個步驟需要設置

  1. 至Google Cloud API設置憑證
  2. 至Keycloak服務設置Client以及Identify Providers (版本17.0.1 )
  3. 撰寫AP Code

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Mermaid Code
sequenceDiagram participant User as [瀏覽器] participant WebAPI as [Web API Service] participant Keycloak participant Google User->>WebAPI: 1. 使用API /user/getAccount WebAPI->>Keycloak: 2. 重定向至認證 Keycloak->>Google: 3. 導向Google認證 activate Google Google-->>User: 4. 提供認證確認畫面 deactivate Google User->>Google: 5. 提供憑據(輸入Google帳號密碼) activate Google Google-->>Keycloak: 6. 授權碼回應 deactivate Google Keycloak->>Google: 7. 請求存取令牌 activate Google Google-->>Keycloak: 8. 回應存取令牌 deactivate Google Keycloak-->>WebAPI: 9. 轉發存取令牌 WebAPI-->>User: 10. API回傳Mario字串

a. 至Google Cloud API設置憑證

  • Step1 : 至 Google Cloud API 平台
  • Step2 : 照下述SOP圖設置
    • Image Not Showing Possible Reasons
      • The image was uploaded to a note which you don't have access to
      • The note which the image was originally uploaded to has been deleted
      Learn More →
    • Image Not Showing Possible Reasons
      • The image was uploaded to a note which you don't have access to
      • The note which the image was originally uploaded to has been deleted
      Learn More →
    • Image Not Showing Possible Reasons
      • The image was uploaded to a note which you don't have access to
      • The note which the image was originally uploaded to has been deleted
      Learn More →
    • Image Not Showing Possible Reasons
      • The image was uploaded to a note which you don't have access to
      • The note which the image was originally uploaded to has been deleted
      Learn More →

b. 至Keycloak服務設置Client以及Identify Providers

  • Step1 : 建置新的Realm (新增基本上只需要輸入Name,以及Enable開ON)
  • Step2 : 建置Clients
  • Step3 : 至Identity Provider 新增IDP (點選Google)
  • Step4 : 照下述設置
    • Image Not Showing Possible Reasons
      • The image was uploaded to a note which you don't have access to
      • The note which the image was originally uploaded to has been deleted
      Learn More →

c. 撰寫Web API Code

Java

  • 套件使用

    • spring-boot-starter-oauth2-client : 讓應用程式可以作為 OAuth 2.0 客戶端運行。
    • spring-boot-starter-security : Spring Security 的基礎套件,它提供了很多安全性相關的功能,比如身份驗證(誰是你)、授權(你能做什麼)、防止跨站請求偽造等。
    • spring-boot-starter-oauth2-resource-server : 讓你的應用程式可以作為 OAuth 2.0 資源服務器運行。
  • configure setting (application.properties)

# 定義 OAuth2 客戶端的 ID。這是用來識別你的應用程式的名稱。 spring.security.oauth2.client.registration.keycloak.client-id=spring # 設定授權模式為 'authorization_code',這是一種常用的 OAuth2 授權流程。 spring.security.oauth2.client.registration.keycloak.authorization-grant-type=authorization_code # 指定 OAuth2 的 scope 為 'openid'。這通常用於 OpenID Connect 流程,用來取得用戶的身份信息。 spring.security.oauth2.client.registration.keycloak.scope=openid # Keycloak 服務的發行者(issuer)URL。這個是 Keycloak 伺服器的地址加上你所使用的 realm。 spring.security.oauth2.client.provider.keycloak.issuer-uri=http://localhost:8080/realms/google-auth # 指定用哪個屬性作為用戶名。在這個例子中,它是 'preferred_username'。 spring.security.oauth2.client.provider.keycloak.user-name- attribute=preferred_username # 設定 JWT(JSON Web Token)的發行者(issuer)URL。這是用於資源服務器(你的應用程式)去驗證令牌的。 spring.security.oauth2.resourceserver.jwt.issuer- uri=http://localhost:8080/realms/google-auth
  • Configure Class撰寫
    • KeycloakLogoutHandler : 負責使用者登出時與 Keycloak(一個開源的身份和存取管理解決方案)的交互。

      • logout :實現了 LogoutHandler 接口的一個方法。當使用者選擇登出時,這個方法會被調用。auth.getPrincipal() 獲取了當前已認證的使用者的詳細信息,然後傳給 logoutFromKeycloak 方法。
      • logoutFromKeycloak : 將登出請求發送到 Keycloak。它拼接了 Keycloak 的登出 URL(endSessionEndpoint)。使用 RestTemplate 來執行 HTTP GET 請求,實際觸發了登出操作。
    • SecurityConfig : 配置你的 Spring Security 設定。

      • sessionAuthenticationStrategy : 提供了一個會話認證策略,確保同一個使用者不會在多個地方同時登入。

      • clientFilterChain : 設定了主要的安全過濾鏈

        http.authorizeRequests() : 設定哪些請求需要認證
        http.oauth2Login() : 啟用 OAuth2 登入
        .logout().addLogoutHandler(keycloakLogoutHandler):加了前面定義的 KeycloakLogoutHandler,使其在登出時被調用。

      • resourceServerFilterChain : 專門用來保護你的資源伺服器(通常是 REST APIs)。

      • authenticationManager : 建立了一個 AuthenticationManager,它是 Spring Security 用來處理認證的主要機制。

C#

  • 套件使用

    • Microsoft.AspNetCore.Authentication.OpenIdConnect : 實現 OpenID Connect 認證
  • DI & Middleware設置

    • DI設置上

      • AddAuthentication : 初始化認證設定

        DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme : 設定表明預設使用 Cookie 來存儲身份資訊。
        DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme : 當需要驗證身份時(挑戰/Challenge),會用 OpenID Connect 方式來完成。

      • AddCookie : 設定 Cookie 的特定選項

        LoginPath = "/Account/Login : 未經認證的使用者訪問受保護的路徑時,會被導向 /Account/Login 這個 URL。

      • AddOpenIdConnect : 設定與 OpenID Connect 有關的選項

        RequireHttpsMetadata = false : 是否強制 HTTPS 連接。設為 false 主要是開發階段使用。
        Authority = "http://localhost:8082/realms/google-auth": 認證伺服器的地址。
        ClientId = "spring": 客戶端(也就是你的應用)的識別碼。
        ResponseType = "code": 表示使用授權碼(Authorization Code)模式。
        Scope.Add("openid") 和 Scope.Add("profile"): 需要獲取哪些使用者資訊。
        TokenValidationParameters: 用於檢查 Token 的有效性。

builder.Services.AddAuthentication(options => { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; }) .AddCookie(options => { options.LoginPath = "/Account/Login"; }) .AddOpenIdConnect(options => { options.RequireHttpsMetadata = false; options.Authority = "http://localhost:8082/realms/google-auth"; options.ClientId = "spring"; options.ResponseType = "code"; options.Scope.Add("openid"); options.Scope.Add("profile"); options.TokenValidationParameters = new TokenValidationParameters { NameClaimType = "preferred_username", RoleClaimType = "roles" }; });
  • Middleware設置
app.UseAuthentication(); app.UseAuthorization();

Demo測試

當AP服務跑起來時,打EndPoint

  • api/user/Login

會先導到Keycloak登入畫面,且會顯示一個Google登入Button

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

此時點選Google按鈕,會跑出一個帳密登入認證如下

登入成功後,即可成功拿到後端回傳的String訊息

d. OAuth Tool 工具網頁測試OAuth

首先進入這個網站,這網站可以用來測試OAuth的驗證功能,只要透過設定就能取得AccessToken之類的相關資訊。

https://oauth.tools/

Step 1. 新增Workspace並且設定你的OAuth Server

這邊依然以Keycloak為舉例,來進行設定

首先創立一個新的WorkSpace

再來設定相關EndPoint

想要查詢Keycloak相關EndPoint可以透過這個網址,並將下面網址的[keyclaokServer] 和[realm]置換成你的設定,然後用瀏覽器開啟就可以看到了。

http://[keycloakServer]/realms/[realm]/.well-known/openid-configuration

其中要注意Issuer就是你Keycloak的realm網址,其他舊照那個Keycloak提供的EndPoint網址無腦貼上就對了。

然後選擇則下一個頁籤我們要設定Client,在這之前確認一下你的Keycloak上的Client設定

若你是20版本以前,確認Client Access Type 是否為 confidential

若是新版的確認是否開啟Client authentication

然後就可以看到Credentials這個頁籤,並把其中的Client secret設定到我們OAuth Tools裡面

設定至OAuth Tools WorkSpace Setting client

設定完後點選新增Flow選擇Implicit flow

設定flow其中寫了profile,email,roles這三個是SCOPE是必要設定的,否則在Keycloak會認證不過。

差點漏掉了在Keycloak的Realm需要設定Valid redirect URIs導向這個工具網頁。

最後就是給他按下RUN進行登入,成功後就會得到一個ACCESSTOKEN呈現在右手邊。

右手邊的AccessToken在這網頁上也有提供Decode所以下面可以看到完成資訊。

Reference

https://ithelp.ithome.com.tw/users/20112470/ironman/4324