最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot整合Keycloak的項(xiàng)目實(shí)踐

 更新時(shí)間:2026年01月15日 09:28:54   作者:d***8172  
本文介紹了如何設(shè)置了Keycloak 服務(wù)器及在SpringBoot中使用 Spring Security OAuth2.0結(jié)合Keycloak實(shí)現(xiàn)認(rèn)證和授權(quán),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

1、概覽

本文將帶你了解如何設(shè)置 Keycloak 服務(wù)器,以及如何使用 Spring Security OAuth2.0 將Spring Boot應(yīng)用連接到 Keycloak 服務(wù)器。

2、Keycloak 是什么?

Keycloak是針對(duì)現(xiàn)代應(yīng)用和服務(wù)的開源身份和訪問管理解決方案。

Keycloak 提供了諸如單點(diǎn)登錄(SSO)、身份代理和社交登錄、用戶聯(lián)盟、客戶端適配器、管理控制臺(tái)和賬戶管理等功能。

本文使用 Keycloak 的管理控制臺(tái),使用 Spring Security OAuth2.0 設(shè)置和連接 Spring Boot。

3、設(shè)置 Keycloak 服務(wù)器

設(shè)置和配置 Keycloak 服務(wù)器。

3.1、下載和安裝 Keycloak

有多種發(fā)行版可供選擇,本文使 Keycloak-22.0.3 獨(dú)立服務(wù)器發(fā)行版。點(diǎn)擊這里從官方下載。

下載完后,解壓縮并從終端啟動(dòng) Keycloak:

unzip keycloak-22.0.3.zip 
cd keycloak-22.0.3
bin/kc.sh start-dev

運(yùn)行這些命令后,Keycloak 會(huì)啟動(dòng)服務(wù)。如果你看到一行類似于Keycloak 22.0.3 [...] started的內(nèi)容,就表示服務(wù)器啟動(dòng)成功。

打開瀏覽器,訪問http://localhost:8080,會(huì)被重定向到http://localhost:8080/auth以創(chuàng)建管理員進(jìn)行登錄:

創(chuàng)建一個(gè)名為initial1的初始管理員用戶,密碼為zaq1!QAZ。點(diǎn)擊 “Create”后,可以看到 “User Created” 的提示信息。

現(xiàn)在進(jìn)入管理控制臺(tái)。在登錄頁面,輸入initial管理員用戶憑證:

3.2、創(chuàng)建 Realm

登錄成功后,進(jìn)入控制臺(tái),默認(rèn)為MasterRealm。

導(dǎo)航到左上角,找到 “Create realm” 按鈕:

點(diǎn)擊它,添加一個(gè)名為SpringBootKeycloak的新 Realm:

單擊 “Create” 按鈕,創(chuàng)建一個(gè)新的 Realm。會(huì)被重定向到該 Realm。接下來的所有操作都將在這個(gè)新的SpringBootKeycloakRealm 中執(zhí)行。

3.3、創(chuàng)建客戶端

現(xiàn)在進(jìn)入 “Clients” 頁面。如下圖所示,Keycloak 已經(jīng)內(nèi)置了客戶端:

我們需要在應(yīng)用中添加一個(gè)新客戶端,點(diǎn)擊 “Create”,將新客戶端命名為login-app

在下一步的設(shè)置中,除了 “Valid Redirect URIs” 字段外,其他字段保留所有默認(rèn)值。該字段包含將使用此客戶端進(jìn)行身份驗(yàn)證的應(yīng)用 URL:

稍后,我們會(huì)創(chuàng)建一個(gè)運(yùn)行于 8081 端口的 Spring Boot 應(yīng)用,該應(yīng)用將使用該客戶端。因此,在上面使用了http://localhost:8081/的重定向 URL。

3.4、創(chuàng)建角色和用戶

Keycloak 使用基于角色的訪問;因此,每個(gè)用戶都必須有一個(gè)角色。

進(jìn)入 “Realm Roles” 頁面:

然后添加用戶角色:

現(xiàn)在有了一個(gè)可以分配給用戶的角色,但由于還沒有用戶,讓我們?nèi)?“Users” 頁面添加一個(gè):

添加一個(gè)名為user1的用戶:

用戶創(chuàng)建后,會(huì)顯示一個(gè)包含其詳細(xì)信息的頁面:

現(xiàn)在進(jìn)入 “Credentials” 選項(xiàng)卡。把初始密碼設(shè)置為xsw2@WS

最后,進(jìn)入 “Role Mappings” 選項(xiàng)卡。為user1分配用戶角色:

4、使用 Keycloak API 生成 Access Token

Keycloak 提供了用于生成和刷新 Access Token 的 REST API,可用于創(chuàng)建自己的登錄頁面。

首先,向如下 URL 發(fā)送 POST 請(qǐng)求,從 Keycloak 獲取 Access Token:

http://localhost:8080/realms/SpringBootKeycloak/protocol/openid-connect/token

請(qǐng)求體應(yīng)包含x-www-form-urlencoded格式的參數(shù):

client_id:<your_client_id>
username:<your_username>
password:<your_password>
grant_type:password

這會(huì)得到一個(gè)access_token和一個(gè)refresh_token。

每次請(qǐng)求受 Keycloak 保護(hù)的資源時(shí),都應(yīng)使用 Access Token,只需將其放在Authorization頭中即可:

headers: {
    'Authorization': 'Bearer' + access_token
}

Access Token 過期后,可以通過向上述相同的 URL 發(fā)送 POST 請(qǐng)求來刷新 Access Token,但請(qǐng)求中應(yīng)包含 Refresh Token,而不是用戶名和密碼:

{
    'client_id': 'your_client_id',
    'refresh_token': refresh_token_from_previous_request,
    'grant_type': 'refresh_token'
}

Keycloak 會(huì)響應(yīng)新的access_tokenrefresh_token。

5、創(chuàng)建和配置 Spring Boot 應(yīng)用

創(chuàng)建一個(gè) Spring Boot 應(yīng)用,并將其配置為 OAuth 客戶端,與 Keycloak 服務(wù)器進(jìn)行交互。

5.1、依賴

使用 Spring Security OAuth2.0 客戶端連接到 Keycloak 服務(wù)器。

首先,在pom.xml中聲明spring-boot-starter-oauth2-clientspring-boot-starter-security依賴:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

使用spring-boot-starter-oauth2-resource-server將身份驗(yàn)證控制委托給 Keycloak 服務(wù)器。它允許我們使用 Keycloak 服務(wù)器驗(yàn)證 JWT Token:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>

現(xiàn)在,Spring Boot 應(yīng)用可以與 Keycloak 交互了。

5.2、Keycloak 配置

將 Keycloak 客戶端視為 OAuth 客戶端。因此,需要配置 Spring Boot 應(yīng)用以使用 OAuth 客戶端。

ClientRegistration類保存客戶端的所有基本信息。Spring 自動(dòng)配置會(huì)查找模式為spring.security.oauth2.client.registration.[registrationId]的屬性,并使用 OAuth 2.0 或 OpenID Connect(OIDC) 注冊(cè)客戶端。

客戶端注冊(cè)配置:

spring.security.oauth2.client.registration.keycloak.client-id=login-app
spring.security.oauth2.client.registration.keycloak.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.keycloak.scope=openid

client-id中指定的值與我們?cè)诠芾砜刂婆_(tái)中命名的客戶端相匹配。

Spring Boot 應(yīng)用需要與 OAuth 2.0 或 OIDC Provider 交互,以處理不同授權(quán)方式的實(shí)際請(qǐng)求邏輯。因此,需要配置 OIDC Provider。它可以根據(jù) Schemaspring.security.oauth2.client.provider.[provider name]的屬性值自動(dòng)配置。

OIDC Provider 配置:

spring.security.oauth2.client.provider.keycloak.issuer-uri=http://localhost:8080/realms/SpringBootKeycloak
spring.security.oauth2.client.provider.keycloak.user-name-attribute=preferred_username

issuer-uri中指定路徑(我們是在 8080 端口啟動(dòng) Keycloak 的)。該屬性標(biāo)識(shí)了授權(quán)服務(wù)器的基本 URI,輸入在 Keycloak 管理控制臺(tái)中創(chuàng)建的 Realm 名稱。此外,還可以將user-name-attribute定義為preferred_username,以便在 Controller 的Principal中填充合適的用戶。

最后,添加針對(duì) Keycloak 服務(wù)器驗(yàn)證 JWT Token 所需的配置:

spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8080/realms/SpringBootKeycloak

5.3、配置類

創(chuàng)建SecurityFilterChainBean 來配置HttpSecurity。使用http.oauth2Login()啟用 OAuth2 登錄。

創(chuàng)建 Security 配置:

@Configuration 
@EnableWebSecurity 
class SecurityConfig { 
    private final KeycloakLogoutHandler keycloakLogoutHandler; 
    SecurityConfig(KeycloakLogoutHandler keycloakLogoutHandler) { 
        this.keycloakLogoutHandler = keycloakLogoutHandler; 
    } 
    @Bean 
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { 
        return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl()); 
    } 
    @Order(1) 
    @Bean 
    public SecurityFilterChain clientFilterChain(HttpSecurity http) throws Exception { 
        http.authorizeRequests() 
            .requestMatchers(new AntPathRequestMatcher("/")) 
            .permitAll() 
            .anyRequest() 
            .authenticated(); 
        http.oauth2Login() 
            .and() 
            .logout() 
            .addLogoutHandler(keycloakLogoutHandler) 
            .logoutSuccessUrl("/"); 
        return http.build(); 
    } 
     
    @Order(2) 
    @Bean 
    public SecurityFilterChain resourceServerFilterChain(HttpSecurity http) throws Exception { 
        http.authorizeRequests() 
            .requestMatchers(new AntPathRequestMatcher("/customers*")) 
            .hasRole("USER") 
            .anyRequest() 
            .authenticated(); 
        http.oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults()));
        return http.build(); 
    } 
    @Bean 
    public AuthenticationManager authenticationManager(HttpSecurity http) throws Exception { 
        return http.getSharedObject(AuthenticationManagerBuilder.class) 
            .build(); 
    } 
}

在上面的代碼中,oauth2Login()方法將OAuth2LoginAuthenticationFilter添加到過濾器鏈中。該過濾器會(huì)攔截請(qǐng)求并應(yīng)用 OAuth 2 身份驗(yàn)證所需的邏輯。oauth2ResourceServer方法將根據(jù) Keycloak 服務(wù)器驗(yàn)證綁定的 JWT Token。

configure()方法中根據(jù)權(quán)限和角色配置訪問權(quán)限。這些約束條件可確保對(duì)/customers/*的每個(gè)請(qǐng)求只有在請(qǐng)求者是具有USER角色的經(jīng)過身份驗(yàn)證的用戶時(shí)才會(huì)獲得授權(quán)。

最后,添加了KeycloakLogoutHandler類來處理 Keycloak 注銷:

@Component
public class KeycloakLogoutHandler implements LogoutHandler {

    private static final Logger logger = LoggerFactory.getLogger(KeycloakLogoutHandler.class);
    private final RestTemplate restTemplate;

    public KeycloakLogoutHandler(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @Override
    public void logout(HttpServletRequest request, HttpServletResponse response, 
      Authentication auth) {
        logoutFromKeycloak((OidcUser) auth.getPrincipal());
    }

    private void logoutFromKeycloak(OidcUser user) {
        String endSessionEndpoint = user.getIssuer() + "/protocol/openid-connect/logout";
        UriComponentsBuilder builder = UriComponentsBuilder
          .fromUriString(endSessionEndpoint)
          .queryParam("id_token_hint", user.getIdToken().getTokenValue());

        ResponseEntity<String> logoutResponse = restTemplate.getForEntity(
        builder.toUriString(), String.class);
        if (logoutResponse.getStatusCode().is2xxSuccessful()) {
            logger.info("Successfulley logged out from Keycloak");
        } else {
            logger.error("Could not propagate logout to Keycloak");
        }
    }

}

KeycloakLogoutHandler類實(shí)現(xiàn)了LogoutHandler,并向 Keycloak 發(fā)送注銷請(qǐng)求。

現(xiàn)在,通過身份驗(yàn)證后,就可以訪問內(nèi)部 customers 頁面了。

5.4、Thymeleaf Web 頁面

使用 Thymeleaf 渲染頁面。

有三個(gè)頁面:

  • external.html- 面向外部的頁面
  • customers.html- 面向內(nèi)部的頁面,其訪問權(quán)限僅限于具有user角色的認(rèn)證用戶
  • layout.html- 一個(gè)簡(jiǎn)單的布局,由兩個(gè)片段組成,分別用于面向外部的頁面和面向內(nèi)部的頁面

Thymeleaf 模板的代碼可在Github上獲取。

5.5、Controller

Web Controller 會(huì)將內(nèi)部和外部 URL 映射到相應(yīng)的 Thymeleaf 模板:

@GetMapping(path = "/")
public String index() {
    return "external";
}
    
@GetMapping(path = "/customers")
public String customers(Principal principal, Model model) {
    addCustomers();
    model.addAttribute("customers", customerDAO.findAll());
    model.addAttribute("username", principal.getName());
    return "customers";
}

/customers會(huì)從 Repository 中檢索所有客戶,并將結(jié)果作為屬性添加到 Model 中。之后,在 Thymeleaf 中遍歷結(jié)果。

為了能夠顯示用戶名,還注入了Principal

注意,這里只是將客戶(customers)作為原始數(shù)據(jù)來顯示,僅此而已。

6、演示

現(xiàn)在,測(cè)試應(yīng)用。通過集成開發(fā)環(huán)境(如 Spring Tool Suite - STS)運(yùn)行 Spring Boot 應(yīng)用,或者在終端運(yùn)行如下命令:

mvn clean spring-boot:run

訪問http://localhost:8081,如下:

現(xiàn)在,點(diǎn)擊 “customers” 戶進(jìn)入內(nèi)部頁面,這是敏感信息的位置。

然后會(huì)被重定向到通過 Keycloak 進(jìn)行身份驗(yàn)證,以檢查我們是否被授權(quán)查看此內(nèi)容:

user1的憑證登錄,Keycloak 會(huì)驗(yàn)證我們的授權(quán),確認(rèn)我們擁有用戶角色,然后會(huì)被重定向到受限的 “customers” 頁面:

現(xiàn)在,整個(gè)流程已經(jīng)完畢了。你可以看到,Spring Boot 無縫地處理了調(diào)用 Keycloak 授權(quán)服務(wù)器的整個(gè)過程。我們無需調(diào)用 Keycloak API 自己生成 Access Token,甚至無需在請(qǐng)求受保護(hù)資源時(shí)明確發(fā)送Authorization頭。

7、總結(jié)

本文介紹了如何如何設(shè)置了 Keycloak 服務(wù)器,以及如何在 Spring Boot 中使用 Spring Security OAuth2.0 結(jié)合 Keycloak 實(shí)現(xiàn)認(rèn)證和授權(quán)。

到此這篇關(guān)于SpringBoot整合Keycloak的項(xiàng)目實(shí)踐的文章就介紹到這了,更多相關(guān)SpringBoot整合Keycloak內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 你應(yīng)該知道的21個(gè)Java核心技術(shù)

    你應(yīng)該知道的21個(gè)Java核心技術(shù)

    Java的21個(gè)核心技術(shù)點(diǎn),你知道嗎?這篇文章主要為大家詳細(xì)介紹了Java核心技術(shù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • 解讀JVM堆大小如何設(shè)置

    解讀JVM堆大小如何設(shè)置

    文章系統(tǒng)講解了JVM堆參數(shù)設(shè)置、分代比例調(diào)整、堆大小計(jì)算方法、監(jiān)控工具使用及調(diào)優(yōu)策略,強(qiáng)調(diào)結(jié)合GC日志分析與壓力測(cè)試優(yōu)化,避免堆過小/過大、元空間未限制等常見問題,提供高并發(fā)、批處理等場(chǎng)景的配置建議
    2025-09-09
  • 關(guān)于QueryWrapper高級(jí)使用示例

    關(guān)于QueryWrapper高級(jí)使用示例

    本文介紹了QueryWrapper的高級(jí)使用方法,包括查詢指定字段、使用MySQL函數(shù)處理字段、設(shè)置查詢限制等,通過select()可查詢指定字段并處理,last()方法實(shí)現(xiàn)limit效果,apply()可在查詢條件中使用函數(shù),這些技巧有助于提升數(shù)據(jù)庫操作的靈活性和效率
    2024-09-09
  • Java?中不全部使用?Static?方法的理由

    Java?中不全部使用?Static?方法的理由

    這篇文章主要介紹了Java?中不全部使用?Static?方法的理由,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-08-08
  • 詳解Java分布式Session共享解決方案

    詳解Java分布式Session共享解決方案

    這篇文章主要介紹了詳解Java分布式Session共享解決方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • java使用Jsoup組件生成word文檔

    java使用Jsoup組件生成word文檔

    java使用Jsoup組件生成word文檔的方法
    2013-11-11
  • Springboot詳細(xì)講解RocketMQ實(shí)現(xiàn)順序消息的發(fā)送與消費(fèi)流程

    Springboot詳細(xì)講解RocketMQ實(shí)現(xiàn)順序消息的發(fā)送與消費(fèi)流程

    RocketMQ作為一款純java、分布式、隊(duì)列模型的開源消息中間件,支持事務(wù)消息、順序消息、批量消息、定時(shí)消息、消息回溯等,本篇我們了解如何實(shí)現(xiàn)順序消息的發(fā)送與消費(fèi)
    2022-06-06
  • SpringBoot 下集成緩存工具類 CacheManager

    SpringBoot 下集成緩存工具類 CacheManager

    這篇文章主要介紹了Springboot下集成緩存工具類CacheManager,想進(jìn)一步了解相關(guān)知識(shí)的同學(xué),可以詳細(xì)閱讀本文
    2023-03-03
  • dubbo自定義異常的完整步驟與測(cè)試

    dubbo自定義異常的完整步驟與測(cè)試

    最近在項(xiàng)目上遇到一個(gè)有關(guān)dubbo的問題,想著給大家總結(jié)下,這篇文章主要給大家介紹了關(guān)于dubbo自定義異常的完整步驟與測(cè)試的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • Spring Cloud調(diào)用Ribbon的步驟

    Spring Cloud調(diào)用Ribbon的步驟

    Ribbon是Netflix發(fā)布的開源項(xiàng)目,主要功能是提供客戶端的軟件負(fù)載均衡算法和服務(wù)調(diào)用。本文將講述Spring Cloud調(diào)用Ribbon的方法
    2021-05-05

最新評(píng)論

垣曲县| 乌鲁木齐市| 积石山| 隆化县| 若尔盖县| 乡城县| 峡江县| 峡江县| 建宁县| 满城县| 历史| 平度市| 库伦旗| 织金县| 襄城县| 晴隆县| 莎车县| 申扎县| 潮安县| 南投县| 安远县| 靖西县| 漯河市| 凤阳县| 察哈| 八宿县| 资兴市| 信丰县| 革吉县| 洛浦县| 泸定县| 宿州市| 贵德县| 肇庆市| 东乡县| 临西县| 临澧县| 龙海市| 山东| 固安县| 蓝田县|