1. 程式人生 > >使用 Keycloak 輕鬆保護 Spring Boot 應用程式

使用 Keycloak 輕鬆保護 Spring Boot 應用程式

儘管安全性是應用程式的一個關鍵點,但是在開發中實施起來確實比較麻煩。更加麻煩的是,這個關鍵點通常不怎麼受重視,實現的效果普遍的 low,而且受到諸多方面的掣肘。而最近安全伺服器的出現,就可以將認證和授權方面的業務邏輯外包和分派出去。 在這些伺服器中,最有希望的是 Keycloak,因為它開放原始碼,靈活,而且未來能適合任何技術亦未可知,它也可以輕鬆地部署並適應於其自身的基礎設施之中。

另外,Keycloak 也不僅僅是一個身份驗證伺服器,它還提供了完整的身份管理系統,可以實現諸如 LDAP 那樣的第三方的使用者聯盟。可以看看這裡

該專案可以在GitHub上找到。

Spring Boot 和 Keycloak

Keycloak 為需要與 Keycloak 例項互動的應用程式提供介面卡。 有用於 WildFly / EAP,NodeJS,JavaScript 的介面卡,當然也有用於 Spring Boot 的介面卡。

設定 Keycloak 服務

你有多個選項來設定一個 Keycloak 伺服器,但最簡單的一個可能是獲取一個獨立的釋出。解壓縮,瞧著! 開啟一個終端,然後切換到你解壓縮的 Keycloak 服務,並從 bin 目錄下執行:

./standalone.sh(bat)

然後開啟瀏覽器,然後轉到進入 http://localhost:8080/auth

由於這是服務的第一次執行,你必須建立一個管理員賬戶才行,所以讓來我們建立一個管理員使用者,使用者名稱為 admin,密碼為 admin:

現在您可以登入到管理控制檯並開始配置 Keycloak。

建立一個新的 Realm

Keycloak 定義了一個 realm 的概念,並且你將在 realm 中定義客戶端,在 Keycloak 中的術語是指由 Keycloak 保護的應用程式。 它可以是 Web App,Java EE 後端,Spring Boot 等等。

所以讓我們建立一個新的 realm,只需點選“新增領域”按鈕:

讓我們稱之為“SpringBoot.”

建立客戶端,角色以及使用者

現在我們需要定義一個客戶端,這就會是我們的 Spring Boot 應用程式。轉到“Clients”部分,然後單擊“Create”按鈕。我們把這個客戶端叫做“product-app”:

在接下來的介面上,我們可以讓大部分東西都保留預設設定,只需要輸入一個有效的重定向 URL,讓 Keycloak 將其用於使用者進行了身份驗證之後。這裡我們輸入這個 URL:“http:// localhost:8081 / *”。

不要忘了把這些配置儲存下來哦!

現在,我們要把需要分配給使用者的角色定義好。建立一個名為“user”的簡單角色:

最後,我們得建立一個使用者。這裡只需要使用者名稱屬性就可以了,這裡我們就叫他“testuser”吧:

最後,我們需要設定一下憑據,所以要轉到使用者的“Credencials(憑據)”選項卡介面,並選擇一個密碼。我會在本文的餘下部分使用“password”,還得確保把“Temporary(臨時)”這個標誌關閉了,除非你是想要使用者可以在首次認證時更改密碼。

現在轉到“Role Mappings(角色對映)”選項卡介面來分配“user”這個角色:

現在我們就完成了 Keycloak 伺服器的配置,可以開始構建 Spring Boot App 了!

建立一個簡單的 App

讓我們來建立一個簡單的 Spring Boot App。你也許會想要使用 Spring Initializrr,這時候要把如下選項給選上:

  • Web

  • Freemarker

  • Keycloak

將你的 App 命名為“product-app”,然後把生成的工程下載下來:

將應用程式匯入你喜歡使用的 IDE 裡面,這裡我會使用 IntelliJ。

我們的應用程式會比較簡單,只包含兩個頁面:

  • 一個 index.html,它將是登入頁面,裡面只包含產品頁面的連結。

  • Products.ftl,它將是我們的產品頁面的模板,只能被通過了身份驗證的使用者訪問到。

首先我們在“/src/resources/static”目錄中建立一個簡單的 index.html 檔案:

<html>

 <head>
   <title>My awesome landing page</title>
 </head>

 <body>
   <h1>Landing page</h1> <a href="/products ">My products</a>
 </body>

</html>

現在,我們需要一個控制器:

@Controller
class ProductController {

  @Autowired ProductService productService;

  @GetMapping(path = "/products ")
  public String getProducts(Model model){
     model.addAttribute("products ", productService.getProducts());
     return "products ";
  }

  @GetMapping(path = "/logout ")
  public String logout(HttpServletRequest request) throws ServletException {
     request.logout();
     return "/ ";
  }
}

你會發現這很簡單,就是定義了產品頁面的對映,然後再為登出操作定義一個對映。你還會注意到,我們呼叫了一個“ProductService”,它會返回一個字串列表,我們把這個列表放到 Spring MVC Model 物件裡面去,所以我們要建立這個服務:

@Component
class ProductService {
  public List<String> getProducts() {
     return Arrays.asList("iPad ","iPod ","iPhone ");
  }
}

我們還需要建立 product.ftl 模板。要在“src/resources/templates”中建立此檔案:

<#import "/spring.ftl " as spring>
   <html>
   <h1>My products</h1>
   <ul>
       <#list products as product>
           <li>${product}</li>
       </#list>
   </ul>
   <p> <a href="/logout ">Logout</a> </p>

   </html>

在這裡,我們簡單地遍歷了 Spring MVC Model 物件中的產品列表,並新增一個從我們的應用程式中登出的連結。

我們要做的就是向 application.properties 中新增一些 keycloak 相關的屬性。

定義 Keycloak 的配置

一些屬性是必須要有的:

keycloak.auth-server-url=http://localhost:8080/auth keycloak.realm=springboot keycloak.public-client=true keycloak.resource=product-app

我們需要定義一些安全方面的約束,就像你在 web.xml 中使用 Java EE 應用的時候要進行的配置一樣:

keycloak.security-constraints[0].authRoles[0]=user keycloak.security-constraints[0].securityCollections[0].patterns[0]=/products/*

在這裡,我們簡單地定義每個向 /products/* 發起的請求都應該通過使用者驗證,而且該使用者得有“user”這個角色。

現在,我們只需要配置最後一個屬性來確保我們的應用程式將會在埠8081上執行:

server.port=8081

這樣我們就都設定好了,可以把應用程式執行起來了!

要執行這個 Spring Boot 應用程式,有很多方式可以選擇。使用 Maven 的話,你可以簡單地像下面這樣做就行了:

mvn clean spring-boot:run

現在導航到“http//localhost8080”,你應該就可以看到登入頁面你了。點選“products”連結,會被重定向到 Keycloak 登入頁面:

使用我們的使用者“testuser/password”進行登入,應該會重定向到產品頁面:

恭喜哦!現在你已經使用 Keycloak 為你的第一個 Spring Boot 應用程式加上了防護措施。現在登出並返回到 Keycloak 管理員控制檯,你就會知道如何去“調整”登入頁面。例如,您可以啟用“Remember Me(記住我)”和“User Registration(使用者註冊)”功能。為此,請點選儲存按鈕並返回到登入介面。在那裡你會這些功能已經新增上了。

引入 Spring Security 支援

如果你是 Spring 使用者而且一直在玩安全方面的東西的話,那麼很有可能就會要用到 Spring Security。而我這裡有一個好訊息:我們還有一個 Keycloak Spring Security Adapter,而且它已經被包含在我們的 Spring Boot Keycloak Starter 中了。

我們來看看如何將 Spring Security 和 Keycloak 放到一起使用。

新增 Spring Security Starter

首先,我們需要 Spring Security 的庫。最容易的方法就是將 spring-boot-starter-security  的 artifact 新增到你的 pom.xml 中:

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

建立一個 SecurityConfig 類

同其它的得到 Spring Security 防護的應用程式一樣, 這裡也需要一個擴充套件自 WebSecurityConfigurerAdapter 的配置類。Keycloak 提供了它自己的一個子類來給你進行再次繼承:

@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter
{
  /**
   * Registers the KeycloakAuthenticationProvider with the authentication manager.
   */
  @Autowired
  public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
     KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
     keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
     auth.authenticationProvider(keycloakAuthenticationProvider);
  }

  @Bean
  public KeycloakConfigResolver KeycloakConfigResolver() {
     return new KeycloakSpringBootConfigResolver();
  }

  /**
   * Defines the session authentication strategy.
   */
  @Bean
  @Override
  protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
     return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception
  {
     super.configure(http);
     http
           .authorizeRequests()
           .antMatchers("/products* ").hasRole("user ")
           .anyRequest().permitAll();
  }
}

讓我們來仔細看看最重要的幾個方法:

  • configureGlobal: 這裡我們修改 Granted Authority Mapper。在 Spring Security 中角色都預設帶上了字首 ROLE_。我們可以在我們的 Realm 配置中把這個改掉,不過這樣做會讓其它不知道這個約定的應用程式感到困惑, 所以這裡我們分配了一個 SimpleAuthorityMapper 來確保不會有字首被加上去。

  • keycloakConfigResolver: Keycloak Spring Security Adapter 預設會從你的 classpath 中找一個叫做 keycloak.json 的檔案。不過這裡我們並不像要利用上 Spring Boot 的屬性檔案支援。

  • configure: 這就是我們定義安全限制的地方。這個相當容易理解。我們要做的就是把帶有“user” 角色的路徑 “/products” 給保護起來。

現在我們可以在我們的 application.properties 檔案中將之前已經定義的安全限制給去掉了,然後新增另外一個屬性來將我們的 KeyCloak 使用者名稱對映到 Principal 名稱上去:

keycloak.principal-attribute=preferred_username

現在我們設定可以將規則諸如到我們的控制器方法中去,並且將使用者名稱放到 Spring 的 MVC model 中:

@GetMapping(path = "/products ")
public String getProducts(Principal principal, Model model){
  model.addAttribute("principal ",principal);
  model.addAttribute("products ", productService.getProducts());
  return "products ";
}

最後,我們可以更新 product.ftl 模板,來把使用者名稱打印出來:

<#import "/spring.ftl " as spring>
   <html>
   <h1>Hello ${principal.getName()}</h1>
   <ul>
       <#list products as product>
           <li>${product}</li>
       </#list>
   </ul>
   <p> <a href="/logout
                            ">Logout</a> </p>

   </html>

再一次重啟你的 App,可以看到它仍然可以執行起來,你也應該能看到你的使用者列印在了產品頁面之上:

相關推薦

使用 Keycloak 輕鬆保護 Spring Boot 應用程式

儘管安全性是應用程式的一個關鍵點,但是在開發中實施起來確實比較麻煩。更加麻煩的是,這個關鍵點通常不怎麼受重視,實現的效果普遍的 low,而且受到諸多方面的掣肘。而最近安全伺服器的出現,就可以將認證和授權方面的業務邏輯外包和分派出去。 在這些伺服器中,最有希望的是 Keycloak,因為它開放原始碼,靈活,而且

10 種保護 Spring Boot 應用的絕佳方法

Spring Boot大大簡化了Spring應用程式的開發。它的自動配置和啟動依賴大大減少了開始一個應用所需的程式碼和配置量,如果你已經習慣了Spring和大量XML配置,Spring Boot無疑是一股清新的空氣。 Spring Boot於2014年首次釋出,自那以後發生

優化Docker的Spring Boot應用程式

Docker功能強大且易於使用。它允許開發人員為他們建立的軟體建立可移植的,獨立的影象。可以可靠且可重複地部署這些影象。您可以輕鬆地從Docker中檢索值,但為了充分利用Docker,有一些對您來說很重要的概念。當您進行持續整合和交付時,如何構建Docker映象

Spring Boot應用程式在啟動時執行一些操作的方法

如果想在生成物件時候完成某些初始化操作,而偏偏這些初始化操作又依賴於依賴注入,那麼就無法在建構函式中實現。為此,可以使用@PostConstruct註解一個方法來完成初始化,@PostConstruct註解的方法將會在依賴注入完成後被自動呼叫。 @PostConstruct是spring框架的註

在Docker環境開發一個Java 8 Spring Boot應用程式

本文旨在讓你瞭解:在你的機器上,不需要Java 8的情況下如何建立一個Java應用程式。就像Python的虛擬環境一樣,那麼這裡我們可以使用Docker。 Python開發人員使用的虛擬環境,用於為不同的專案建立和管理獨立的環境,每個使用不同版本的Python

使用Payara資料來源在Payara伺服器下執行Spring Boot應用程式

步驟1:在Payara 5中新增Connector / J(JDBC MySQL Connector) 為了與MySQL通訊,似鯖水狼牙魚需要聯結器/ J。下載並解壓縮Connector / J的存檔後,找到名為mysql-connector-java-5.1.47.jar的JAR檔案 

構建一個執行在Azure虛擬機器上的MySQL Spring Boot應用程式

關鍵要點 從GitHub中獲取一個簡單的Spring Boot Java應用程式。 將應用程式連線到Azure MySQL資料庫服務。 在Azure上配置一個執行WildFly的Linux VM。 將示例應用程式部署到WildFly伺服器。 最近,我被要求構建一個在 

使用JWT保護你的Spring Boot應用

作者 freewolf 原創文章轉載請標明出處 關鍵詞 Spring Boot、OAuth 2.0、JWT、Spring Security、SSO、UAA 寫在前面 最近安靜下來,重新學習一些東西,最近一年幾乎沒寫過程式碼。整天疲於奔命的日子終於結束了

深入JVM分析spring-boot應用hibernate-validator

using virtual orf replace vid share create sun abs 問題 可重現的Demo代碼:demo.zip 最近排查一個spring boot應用拋出hibernate.validator NoClassDefFoundE

Spring Boot應用的啟動和停止(Spring Boot應用通過start命令啟動)

系統服務 路徑 att framework 兩種 只需要 admin 引入 top Spring Boot,作為Spring框架對“約定優先於配置(Convention Over Configuration)”理念的最佳實踐的產物,它能幫助我們很快捷

Docker 容器整合 Spring Boot 應用

docker 微服務 容器 devops jfrog 在本文中,我們將重點介紹如何對 Spring Boot 應用程序進行 Docker 容器化以在獨立的環境(即容器)中運行它。此外,我們還會展示如何創建容器的集成,它們彼此依賴並在虛擬專用網絡中彼此鏈接。我們還能看到如何通過單個命令進行統

構建Spring Boot應用鏡像

unzip pin sse java 我們 pre lib 鏡像 cmd 1、在Dockerfile所在目錄,解壓縮maven生成的jar包 unzip <path-to-app-jar>.jar -d app 2、Dockerfile 我們把應用的內容分成

Spring Boot應用程序遷移到Java9:兼容性

sam 最新 ive 就業 ont add home index world 將 Spring Boot 應用程序遷移到 Java 9:兼容性   隨著 Java 9 的到來,關於如何遷移應用程序以使用模塊系統有很多的討論。遺憾的是,大多數文章的焦點都集中於簡單的 Hell

Spring Boot 應用AOP

通知 匹配 ide CA AS 結束 RR 依賴 表示 # Spring Boot 應用AOP 一、在pom中添加依賴 <dependency> <groupId>org.springframework.boot</groupId>

開發者測試-采用精準測試工具對Spring Boot應用進行測試

新建 之間 分享 maven倉庫 第一個 項目 數據傳輸 寫實 blog 簡介:本文主要介紹把現今主流的springboot框架項目和精準測試工具進行結合和應用,通過精準測試的數據穿透、數據采集、測試用例與代碼的雙向追溯、數據分析等一系列精準測試的特有功能,達到對項目質量的

Spring Boot應用監控的實戰教程

事件 oot load 增加 lin keyword 微服務 processor cli 概述 Spring Boot 監控核心是 spring-boot-starter-actuator 依賴,增加依賴後, Spring Boot 會默認配置一些通用的監控,比如 jvm

用 Docker、Gradle 來構建、運行、發布一個 Spring Boot 應用

repo com ase exp base ide 默認 相關 conf 本文演示了如何用 Docker、Gradle 來構建、運行、發布來一個 Spring Boot 應用。Docker 簡介Docker 是一個 Linux 容器管理工具包,具備“社交”方面,允許用戶發布

Spring Boot應用總結更新

req 表示 resources list 升級 文章 depend 單引號 nbsp SpringBoot的產生背景: SpringBoot的產生背景伴隨著微服務,微服務的相關概念參考上一篇的博客,分布式架構理論; 微服務的宏觀概念理解: 將一個大應用拆分成多個小應用,一

spring-boot入門程式詳解

1.建立一個普通的maven專案,專案名為boot-learnning 2.在pom.xml新增parent依賴 <parent> <groupId>org.springframework.boot</groupId> <

SpringBoot學習_使用嚮導快速建立Spring Boot應用

新建專案 起包名模組名等 選擇模組(其實就是選擇starters) 例如我要匯入校驗功能選勾Validation他就會匯入JSR-303了 選最基本的web 然後下一步再finish就可以了 然後它就會聯網從springboot官網幫我們生成專案 生成的專案中已經有一個主程式了,我們