天天看點

Keycloak 13 自定義使用者身份認證流程(User Storage SPI)

Keycloak

版本:13.0.0

spring-boot 項目 Github

user-storage-spi 項目 Github

介紹

Keycloak 是為現代應用程式和服務提供的一個開源的身份和通路管理的解決方案。

Keycloak 在測試環境可以使用内嵌資料庫,生産環境需要重新配置資料庫。以下将一一介紹如何使用内嵌資料庫、重新配置資料庫。

特别需要注意 Keycloak 是在 WildFly 上建構的。

目錄

    • 安裝
      • 系統要求
      • 目錄結構
      • 使用 Docker 安裝 Keycloak
    • 使用
      • 建立 realm 和 使用者
        • 建立 realm
        • 建立使用者
        • 建立使用者登入控制台
    • Spring-Boot 認證
      • 注冊用戶端到 Keycloak 中
        • 認證
          • Bearer 令牌
          • 初始化通路令牌
          • 注冊通路令牌
          • Keycloak Representations
          • Keycloak 擴充卡配置
          • OIDC 動态用戶端注冊
          • 用戶端注冊政策
      • 管理用戶端
        • OIDC 用戶端
          • 建立 OIDC 用戶端
    • 使用外部資料庫
      • 使用者存儲 SPI
        • 打包和部署
        • 自定義使用者存儲 Provider
        • Spring-boot 使用外部使用者認證
    • Keycloak 角色
      • 使用資料庫使用者登入

  • Java8 JDK
  • 至少 512M 記憶體
  • 至少 1G 磁盤
  • 如果要設定 Keycloak 叢集則需要資料庫,比如:PostgreSQL、Oracle、MySQL 等
  • 如果要運作叢集,需要網絡支援廣播。當然也可以不需要,隻不過需要更改一堆配置

  • bin/ —— 各種啟動服務、伺服器上執行管理的腳本
  • domain/ —— 叢集模式下的配置檔案和工作目錄
  • modules/ —— 服務使用的 Java 包
  • standalone/ —— 單機模式下的配置檔案和工作目錄
  • standalone/deployments/ —— 你自定義的擴充檔案
  • themes/ —— 界面主題檔案

  1. 啟動容器
    docker run -p 10010:8080 -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin quay.io/keycloak/keycloak:13.0.0
               
  2. 成功啟動後通路:

    http://127.0.0.1:10010/

    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)
  3. 登入 Keycloak 服務

    a. 點選 Administration Console

    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)
    b. 輸入賬号:admin,密碼:admin
    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)
    c. 進入控制台界面
    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)

建立一個 realm 和使用者以通路内置的賬戶管理控制台。把 realm 想像成租戶的概念。

  • Master realm

    —— 這個 realm 是初始化時建立的,它包含超級管理者。使用這個 realm 管理其它的 realm。
  • Other realm

    —— 超級管理者建立的 realm 。在這些 realm 裡,超級管理者建立使用者和應用程式,使用者擁有應用程式。
Keycloak 13 自定義使用者身份認證流程(User Storage SPI)

  1. 點選

    Add realm

    按鈕
    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)
  2. 輸入 realm 名稱
    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)
  3. create

    按鈕完成建立

    點選建立完成 demo realm 建立。

  1. 切換 realm 到 Demo
    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)
  2. 建立使用者,Users -> Add User,輸入

    Username

    ,點選

    Save

    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)
  3. 設定密碼
    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)

  1. 退出 admin 賬戶登入
  2. 位址輸入:

    http://127.0.0.1:10010/auth/realms/demo/account/

    Sign In

    按鈕,使用新建立的使用者 Zhang 登入
    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)
  3. 設定新密碼
    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)
  4. 登入成功
    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)

應用程式或服務為了能使用 Keycloak,必須在 Keycloak 中注冊一個用戶端。可以通過超級管理者界面注冊,用戶端也可以自己通過 Keycloak 服務注冊。

用戶端注冊服務提供内置支援:Keycloak Client Representations、OIDC 用戶端中繼資料、SAML 實體描述。用戶端注冊服務位址是:

/auth/realms/<realm>/clients-registrations/<provider>

内置的

provider

  • default —— Keycloak Client Representation(JSON)
  • install —— Keycloak Adapter Configuration(JSON)
  • openid-connect —— OIDC 用戶端中繼資料描述(JSON)
  • saml2-entity-descriptor —— SAML 實體描述者(XML)

調用用戶端注冊服務需要令牌。令牌可以是 bearer 令牌,初始化通路令牌或者注冊令牌。不需要令牌注冊用戶端也可以,但是需要配置用戶端注冊政策。

Bearer 令牌可以代表使用者或者服務賬戶。調用端點需要以下權限:

  • create-client 或者 manage-client —— 建立用戶端
  • view-client 或者 manage-client —— 檢視用戶端
  • manage-client —— 更新或者删除用戶端

如果使用 Bearer 令牌建立用戶端,推薦使用來自服務賬戶(

create-client

角色)的令牌。

推薦使用初始化通路令牌注冊用戶端。初始化通路令牌隻能用于建立用戶端,并且可以配置有效期,同時可以配置可以建立多少用戶端。

初始化通路令牌可以通過超級管理者控制台建立。

Keycloak 13 自定義使用者身份認證流程(User Storage SPI)
Keycloak 13 自定義使用者身份認證流程(User Storage SPI)

點選儲存,完成令牌的建立。

當點選儲存以後會生成令牌,這個令牌如果忘記複制了,那麼就隻能重新建立了。使用 bearer 令牌:

Authorization: bearer eyJhbGciOiJSUz...
           

當通過用戶端注冊服務建立用戶端時,傳回值會包含一個注冊通路令牌。注冊通路令牌提供檢索用戶端配置、更新或者删除用戶端的權限。注冊通路令牌使用方式和 bear 令牌、初始化通路令牌的使用方式是一樣的。注冊通路令牌是一次性的,當它使用時,傳回值裡總會包含一個新的令牌。

如果用戶端在用戶端注冊服務之外建立,注冊通路令牌就不會和用戶端關聯起來了。但可以在超級管理者控制台生成注冊通路令牌。

default

用戶端注冊提供商可以建立、檢索、更新、删除用戶端。使用 Keycloak Client Representation 轉換提供配置用戶端支援,就像在超級管理者控制台配置的一樣。

建立 Client Representation(JSON)執行 HTTP POST 請求

/auth/realms/<realm>/clients-registrations/default

檢索 Client Representation 執行 GET 請求

/auth/realms/<realm>/clients-registrations/default/<client id>

它也會傳回新的注冊通路令牌。

要更新 Client Representation 執行 HTTP PUT 請求

/auth/realms/<realm>/clients-registrations/default/<client id>

它也會傳回一個新的注冊通路令牌。

要删除 Client Representation 執行 HTTP DELETE 請求

/auth/realms/<realm>/clients-registrations/default/<client id>

installation

用戶端注冊提供商可以用于為用戶端擷取擴充卡配置。除了令牌身份驗證之外,還可以使用 HTTP basic 認證(通過用戶端憑證)。使用下列請求頭以完成 HTTP basic 認證:

Authorization: basic BASE64(client-id + ':' + client-secret)
           

要擷取擴充卡配置執行 HTTP GET 請求:

/auth/realms/<realm>/clients-registrations/install/<client id>

公共用戶端不需要身份認證。這意味着 JavaScript 擴充卡可以通過以上 URL 直接從 Keycloak 加載用戶端配置。

終端在 Keycloak 中注冊用戶端

/auth/realms/<realm>/clients-registrations/openid-connect[/<client id>]

在 OIDC 發現中可以為 realm 找到終端,

/auth/realms/<realm>/.well-known/openid-configuration

Keycloak 目前支援兩種方式注冊用戶端(通過用戶端注冊服務)。

  • 認證請求 —— 注冊用戶端請求要麼包含初始化通路令牌,要麼包含 Bearer 令牌
  • 匿名請求 —— 注冊用戶端不需要包含任何令牌

匿名用戶端注冊請求是非常有趣和強大的功能,任何人都可以注冊用戶端并且沒有限制。是以提出了用戶端注冊政策 SPI,它提供了一個限制的方式(誰能注冊,在什麼條件下)。

在 Keycloak 超級管理者控制台中,你可以看到匿名請求政策配置和認證請求政策配置。

Keycloak 13 自定義使用者身份認證流程(User Storage SPI)

目前支援的政策:

  • Trusted Hosts Policy —— 可以配置信任的 host 和域名。預設的,沒有白名單 host,是以匿名用戶端注冊實際上是禁用的。
  • Consent Required Policy —— 新注冊的用戶端

    Consent Allowed

    開關是啟動的。是以身份認證成功後,使用者将看到準許會話(如果需要的話)。
  • Protocol Mapper Policy —— 允許配置協定映射實作白名單。
  • Client Scope Policy —— 允許

    Client Scopes

    白名單,用于新注冊的用戶端或者更新的用戶端。
  • Full Scope Policy —— 新注冊的用戶端

    Full Scope Allowed

    開關是關閉的。意味這這些用戶端沒有任何 realm 角色或者用戶端角色。
  • Max Clients Policy —— 如果注冊的用戶端數量在 realm 中大于或等于設定值将被駁回。預設值 200。
  • Client Disabled Policy —— 新注冊用戶端是禁用的。意味着超級管理者需要手動通過和啟用新注冊的用戶端。這個政策預設不啟用。

用戶端是使用者請求身份認證的實體。用戶端有兩種格式。第一種是單點登入的(SSO)。另一種是類型是擷取通路令牌然後代表使用者通路服務。

  1. 用戶端清單
    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)
  2. 添加用戶端,

    Client ID

    是用戶端的身份辨別。下一步選擇用戶端協定

    openid-connect

    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)
    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)

    Client ID

    資料字母字元串,用于用戶端身份識别(當 OIDC 請求時)。

    Name

    用戶端名稱。

    Description

    用戶端描述。

    Enabled

    如果關閉,用戶端将不允許請求驗證。

    Consent Required

    如果打開,使用者将得到一個準許頁面(用于詢問使用者是否授權應用程式通路)。頁面同時顯示用戶端要通路的中繼資料資訊,使用者可以看到用戶端要通路的資訊。

    Access Type

    OIDC 用戶端類型。

    • confidential:機密通路類型用于服務端用戶端(需要執行浏覽器登入和需要用戶端密碼)。這個類型用于服務端應用程式。
    • public:Public 通路類型是用戶端類型用戶端(需要執行浏覽器登入)。用戶端類型應用程式沒有安全儲存秘密的方式。相反,通過為用戶端配置正确的重定向 URI 來限制通路非常重要。
    • bearer-only:Bearer-only 通路類型意味着應用程式僅允許 bearer 令牌請求。如果打開這個,應用程式不能參與浏覽器登入。

    Standard Flow Enabled

    如果打開這個,用戶端将使用 OIDC 授權碼工作流。

    Implicit Flow Enabled

    如果打開這個,用戶端将使用 OIDC 隐式工作流。

    Direct Access Grants Enabled

    如果打開這個,用戶端将使用 OIDC 直接通路授權。

    OAuth 2.0 Device Authorization Grant Enabled

    如果打開這個,用戶端将使用 OIDC 裝置授權許可。

    OpenID Connect Client Initiated Backchannel Authentication Grant Enabled

    如果打開這個,用戶端将使用 OIDC 用戶端初始化後端管道認證許可。

    Root URL

    如果 Keycloak 不使用任何相對 URL,這個值就是預留值。

    Valid Redirect URIs

    這個是必填字段。輸入 URL 模版然後點選 + 号添加。點選 - 号移除 URL。記住,最後還要點選

    Sava

    按鈕。通配符 * 隻能用于 URI 的末端,例如:

    http://host.com/*

    注冊重定向 URL 模版時,你應該考慮避免被攻擊。

    Base URL

    如果 Keycloak 要連結用戶端,這個值需要設定。

    Admin URL

    為 Keycloak 指定用戶端擴充卡,這個值是用戶端回調終端。Keycloak 服務将使用這個 URI 回調(比如:推送取消政策、執行後端管道登出、其它超級管理者操作)。對于 Keycloak servlet 擴充卡來說,這個值是 servlet 應用程式的 root URL。

    Web Origins

    這個設定是以 CORS 為中心。

  3. 保密用戶端證書

    如果用戶端

    access type

    設定為

    confidential

    時,頁面将會顯示

    Credentials

    标簽。注意,選擇

    Confidential

    标簽要儲存以後才會能看到

    Credentials

    标簽。
    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)
    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)

    Client Authenticator

    下拉框指定你的加密用戶端證書類型。預設是

    Client Id and Secret

    。secret 自動生成,并且

    Regenerate Secret

    按鈕可以重新生成 secret。

    此外,可以選擇

    Signed Jwt

    或者

    X509 Certificate

    驗證代替 secret。

    Signed JWT

    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)
    當選擇 Signed Jwt 類型時,你需要為用戶端生成私鑰和證書。私鑰用于 JWT 簽名,證書用于服務端驗證簽名。點選

    Generate new keys and certificate

    按鈕生成私鑰和證書。

    也可以使用其它工具生成,然後導入。

  4. 建立 Spring-boot 項目
    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)
  5. 建立 Keycloak 用戶端,導航到

    http://127.0.0.1:10010/

    ,切換到

    Demo

    realm ,點選

    Clients

    菜單,點選

    Create

    按鈕,建立一個

    Demo

    realm 下的用戶端。用戶端 ID 為:spring-boot-toy。選擇

    Access Type

    confidential

    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)
  6. 建立角色 toy-admin,并給使用者賦予角色
    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)
    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)
    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)
  7. Spring 項目添加 Maven 引用
    <?xml version="1.0" encoding="UTF-8"?>
     <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
         <modelVersion>4.0.0</modelVersion>
         <parent>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-parent</artifactId>
             <version>2.3.10.RELEASE</version>
             <relativePath/> <!-- lookup parent from repository -->
         </parent>
         <groupId>com.toy.keycloak</groupId>
         <artifactId>toy-keycloak</artifactId>
         <version>0.0.1-SNAPSHOT</version>
         <name>toy-keycloak</name>
    
         <properties>
             <java.version>1.8</java.version>
         </properties>
         <dependencies>
             <dependency>
                 <groupId>org.keycloak</groupId>
                 <artifactId>keycloak-spring-boot-starter</artifactId>
             </dependency>
    
             <dependency>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-devtools</artifactId>
                 <scope>runtime</scope>
                 <optional>true</optional>
             </dependency>
             <dependency>
                 <groupId>org.projectlombok</groupId>
                 <artifactId>lombok</artifactId>
                 <optional>true</optional>
             </dependency>
             <dependency>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-starter-test</artifactId>
                 <scope>test</scope>
                 <exclusions>
                     <exclusion>
                         <groupId>org.junit.vintage</groupId>
                         <artifactId>junit-vintage-engine</artifactId>
                     </exclusion>
                 </exclusions>
             </dependency>
         </dependencies>
    
         <dependencyManagement>
             <dependencies>
                 <dependency>
                     <groupId>org.keycloak.bom</groupId>
                     <artifactId>keycloak-adapter-bom</artifactId>
                     <version>13.0.0</version>
                     <type>pom</type>
                     <scope>import</scope>
                 </dependency>
             </dependencies>
         </dependencyManagement>
    
         <build>
             <plugins>
                 <plugin>
                     <groupId>org.springframework.boot</groupId>
                     <artifactId>spring-boot-maven-plugin</artifactId>
                     <configuration>
                         <excludes>
                             <exclude>
                                 <groupId>org.projectlombok</groupId>
                                 <artifactId>lombok</artifactId>
                             </exclude>
                         </excludes>
                     </configuration>
                 </plugin>
             </plugins>
         </build>
    
     </project>
    
               
  8. 暴露 Api 接口
    package com.toy.keycloak.webapi;
    
     import org.springframework.web.bind.annotation.GetMapping;
     import org.springframework.web.bind.annotation.RequestMapping;
     import org.springframework.web.bind.annotation.RestController;
    
     /**
     * @author Zhang_Xiang
     * @since 2021/5/11 16:56:57
     */
     @RestController
     @RequestMapping("temp")
     public class TempController {
    
         @GetMapping("weather")
         public String weather(){
             return "晴天☀️";
         }
    
     }
    
               
  9. 配置

    使用 Tomcat、Undertow、Jetty 不需要額外配置。在

    application.properties

    中配置 Keycloak 如下:
    keycloak.realm=demo  # realm 名稱
     keycloak.auth-server-url=http://127.0.0.1:10010/auth   # Keycloak 基礎服務位址
     keycloak.ssl-required=external
     keycloak.resource=spring-boot-toy   # 應用程式用戶端 ID
     keycloak.credentials.secret=91437668-b8f8-425b-ba9d-38439115dfbc
     keycloak.use-resource-role-mappings=true
     keycloak.securityConstraints[0].authRoles[0]=toy-admin
     keycloak.security-constraints[0].securityCollections[0].patterns[0]=/*
               
    設定

    keycloak.enabled = false

    可以停用 Keycloak 。
  10. 啟動 Spring 應用程式,并通路

    http://localhost:8080/temp/weather

    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)
    輸入使用者名

    zhang

    ,密碼

    123456

    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)
  11. 管理登入使用者會話,使用者登入後,進入 Keycloak 管理背景,切換到 Demo realm 可以看到目前登入的會話清單。
    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)

    Logout all

    按鈕,所有使用者都将登出。

Keycloak 内嵌了 H2 記憶體資料庫。Keycloak 預設使用 H2 持久化資料。H2 資料庫不适用于高并發場景并且不适用于叢集。

Keycloak 使用兩層技術持久化關系資料。底層技術是 JDBC。JDBC 用于連接配接 RDBMS。每個資料庫提供商都有不同的 JDBC 驅動。頂層技術用于持久化的是 Hibernate JPA。

使用使用者存儲 SPI 擴充 Keycloak 以連接配接外部使用者資料和證書存儲。當 Keycloak 運作時查找使用者時,比如使用者登入,Keycloak 執行幾個步驟定位使用者。首先看使用者是在在使用者緩存中,然後在本地資料庫中查找,如果找不到,循環使用者存儲 SPI 執行查找。

使用者存儲 SPI 提供商實作打包和部署和 Java EE 元件相似。預設不啟用元件,如果要啟用需要在 Keycloak 超級管理者控制台界面中配置

User Feberation

使用者存儲提供商打包為 JAR 然後部署到 Keycloak 運作時或者從 Keycloak 運作時取消部署,就像 WildFly 應用程式服務部署服務一樣。你也可以直接拷貝 JAR 包到

standalone/deployments/

伺服器目錄,或者使用 JBoss CLI 執行部署。

為了 Keycloak 能識别服務提供商,你需要添加一個檔案到 JAR 包中:

META-INF/services/org.keycloak.storage.UserStorageProviderFactory

。這個檔案必須包含實作

UserStorageProviderFactory

類的全路徑:

org.keycloak.examples.federation.properties.ClasspathPropertiesStorageFactory
org.keycloak.examples.federation.properties.FilePropertiesStorageFactory
           

使用已有使用者資料庫。

MysqlUserStorageProvider 實作了很多接口,實作

UserStorageProvider

是實作是 SPI 的基本要求,換句話說,不實作

UserStorageProvider

就不能實作 SPI,

UserLookupProvider

用于實作從外部資料庫查找使用者以實作使用者登入,

UserQueryProvider

定義複雜查詢以查找使用者,

CredentialInputValidator

驗證不同的證書類型(比如:驗證登入密碼)。

  1. provider

    public class MysqlUserStorageProvider implements UserLookupProvider, UserQueryProvider, CredentialInputValidator, UserStorageProvider {
    
        protected KeycloakSession session;
        protected ComponentModel model;
    
        public MysqlUserStorageProvider(KeycloakSession session, ComponentModel model) {
            this.session = session;
            this.model = model;
        }
    
        ...
    }
    
               
  2. ProviderFactory

    ,這裡的

    ProviderConfigProperty

    用于自定義标簽,換句話說,在這裡定義了标簽以後,可以在 Keycloak 管理界面設定值,代碼可以直接讀取到這些值。添加自定義 SPI 時,要留意添加在什麼 realm 下。
    public class MysqlUserStorageProviderFactory implements UserStorageProviderFactory<MysqlUserStorageProvider> {
    
    protected final List<ProviderConfigProperty> configMetadata;
    
    public MysqlUserStorageProviderFactory() {
        configMetadata = ProviderConfigurationBuilder.create()
                .property()
                .name(CONFIG_KEY_JDBC_DRIVER)
                .label("JDBC Driver Class")
                .type(ProviderConfigProperty.STRING_TYPE)
                .defaultValue("org.h2.Driver")
                .helpText("Fully qualified class name of the JDBC driver")
                .add()
                .property()
                .name(CONFIG_KEY_JDBC_URL)
                .label("JDBC URL")
                .type(ProviderConfigProperty.STRING_TYPE)
                .defaultValue("jdbc:h2:mem:customdb")
                .helpText("JDBC URL used to connect to the user database")
                .add()
                .property()
                .name(CONFIG_KEY_DB_USERNAME)
                .label("Database User")
                .type(ProviderConfigProperty.STRING_TYPE)
                .helpText("Username used to connect to the database")
                .add()
                .property()
                .name(CONFIG_KEY_DB_PASSWORD)
                .label("Database Password")
                .type(ProviderConfigProperty.STRING_TYPE)
                .helpText("Password used to connect to the database")
                .secret(true)
                .add()
                .property()
                .name(CONFIG_KEY_VALIDATION_QUERY)
                .label("SQL Validation Query")
                .type(ProviderConfigProperty.STRING_TYPE)
                .helpText("SQL query used to validate a connection")
                .defaultValue("select 1")
                .add()
                .build();
    }
    
    @Override
    public MysqlUserStorageProvider create(KeycloakSession session, ComponentModel model) {
        return new MysqlUserStorageProvider(session, model);
    }
    
    @Override
    public String getId() {
        return "user-center-provider";
    }
    
    @Override
    public List<ProviderConfigProperty> getConfigProperties() {
        return configMetadata;
    }
    
    @Override
    public void validateConfiguration(KeycloakSession session, RealmModel realm, ComponentModel config) throws ComponentValidationException {
        try (Connection c = DbUtil.getConnection(config)) {
            System.out.println(config.get(CONFIG_KEY_VALIDATION_QUERY));
            c.createStatement().execute(config.get(CONFIG_KEY_VALIDATION_QUERY));
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
            throw new ComponentValidationException("Unable to validate database connection", ex);
        }
    }
    }
               
    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)
    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)
  3. 檢視使用者清單
    Keycloak 13 自定義使用者身份認證流程(User Storage SPI)

  1. application.properties

    keycloak.realm=demo
     keycloak.auth-server-url=http://127.0.0.1:10010/auth
     keycloak.ssl-required=external
     keycloak.resource=spring-boot-toy
     keycloak.credentials.secret=91437668-b8f8-425b-ba9d-38439115dfbc
     keycloak.use-resource-role-mappings=true
     keycloak.verify-token-audience=true
     keycloak.securityConstraints[0].authRoles[0]=user
     keycloak.security-constraints[0].securityCollections[0].patterns[0]=/temp/weather
               
    • resource:用戶端 ID
    • use-resource-role-mappings:當設定為 true 時,OIDC Java 擴充卡将 Token 中查找應用程式級使用者角色映射。設定為 false 時,将從 realm 裡查找使用者角色映射。預設設定為 false。
    • ssl-required:確定所有和 Keycloak 通訊的請求是 HTTPS,生産環境應設定為

      all

      ,預設值是

      external

      ,即外部請求需要 HTTPS,可選值是:

      all

      external

      none

    • verify-token-audience:設定為 true 時,Bearer Token 進行身份認證時,擴充卡會驗證令牌是否包含用戶端名稱。啟用将改善安全性(推薦)。

一個 Realm 有多個用戶端,一個用戶端有多個使用者。在 Keycloak 有3種角色:

  • Realm Role:全局角色,屬于指定 realm。任何用戶端都可以通路這個角色,并且把這個角色映射到任何使用者。
  • Client Role:屬于指定用戶端的角色。隻能映射到該用戶端下的使用者。
  • Composite Role:多個角色的組合。
Keycloak 13 自定義使用者身份認證流程(User Storage SPI)

在用戶端設定中啟用

Service Accounts Enabled

,在 demo Realm 中添加

ordinary_user

角色。

Keycloak 13 自定義使用者身份認證流程(User Storage SPI)

Service Account Roles

标簽中添加

ordinary_user

Keycloak 13 自定義使用者身份認證流程(User Storage SPI)

添加該角色以後,切換到

User

标簽,可以看到使用者中已經關聯了角色。

Keycloak 13 自定義使用者身份認證流程(User Storage SPI)

  1. 添加角色限制

    ordinary_user

    keycloak.realm=demo
    keycloak.auth-server-url=http://127.0.0.1:10010/auth
    keycloak.ssl-required=external
    keycloak.resource=spring-boot-toy
    keycloak.credentials.secret=91437668-b8f8-425b-ba9d-38439115dfbc
    keycloak.use-resource-role-mappings=true
    keycloak.verify-token-audience=true
    keycloak.securityConstraints[0].authRoles[0]=toy-admin
    keycloak.security-constraints[0].auth-roles[1]=ordinary_user
    keycloak.security-constraints[0].securityCollections[0].patterns[0]=/temp/weather
               
  2. 啟動服務,通路 localhost:8080/temp/weather,輸入自定義資料庫中的使用者、密碼,以通路接口。

繼續閱讀