使用Keycloak實現安全的SpringBoot微服務
Keycloak
它提供了身份和訪問管理的有用功能:
- 單點登錄(SSO),身份代理和社交登錄
- 用戶聯合
- 客戶端適配器
- 管理控制臺和帳戶管理控制臺。
雖然安全性是任何應用程序的一個重要方面,但安全性的實現部分是復雜和困難的。通常,它在代碼中經常被忽略或執行不當和幹擾。
開發人員需要安全服務器,允許外包和授權認證和授權方面。他們想要一種能夠自動開發應用程序安全功能的工具,這通常是一項復雜的任務。
Keycloak是最有前途的開源IDAM(身份和訪問管理)服務器之一,它與任何技術無關,可以在自己的基礎架構中輕松部署/適應。
Keycloak嘗試解決基於REST的Web應用程序和Web服務的單點登錄。Keycloak的最終目標是使安全性足夠簡單,以便作為服務和應用程序中的安全模塊插入。安全功能很混亂,當開發人員手動為自己編寫時,它會變得更危險,更容易出錯。Keycloak通過提供開箱即用的安全功能幫助我們,並且可以根據任何組織的個性化需求輕松定制。
Keycloak可以幫助我們在應用程序中引入這些功能:
- 用於登錄,註冊,管理和帳戶管理的可自定義用戶界面
- 集成到現有LDAP和活動目錄服務器
- 將身份驗證委托給Twitter和Github等第三方身份提供商
安裝:
有不同的方法來安裝keycloak。最簡單的是只需下載Keycloak,這是一種獨立的安裝模式,只需將其解壓縮即可。你完成了!現在打開一個終端並轉到解壓縮的Keycloak服務器並導航到bin目錄 - 然後只需運行以下命令:
./standalone.sh(bat)
安裝完成後,打開瀏覽器並轉到http:// localhost:8080 / auth。
默認情況下,Keycloak附帶一個H2數據庫,但如果你選擇RDMS,你可以使用帶有RDMS的Keycloak。
由於您是第一次運行服務器,因此您必須創建管理員用戶。讓我們創建一個管理員用戶,其中“admin”作為用戶名,“admin”作為密碼。
創造一個新領域
在Keycloak中,領域是您定義客戶端的地方。這意味著這些客戶端是將由Keycloak保護的應用程序 - 可能是Web應用程序或Spring Boot。
註意:‘Master‘是Keycloak的默認領域。讓我們只需點擊“添加領域”按鈕即可創建新領域
創建客戶端
Spring Boot應用程序是您的客戶端。就這麽簡單。在Keycloak中,客戶端是使用Keycloak保護的應用程序。
讓我們看看如何在Keycloak中創建客戶端:
- 轉到門戶網站中的“Client”菜單
- 單擊“創建”按鈕
- 為Client-Id提供名稱。我們稱之為Rbi-Service。
在下一個屏幕上將所有內容保持為默認值,您需要的只是輸入一個有效的重定向URL,Keycloak將在該應用程序中對用戶進行身份驗證時使用該URL。我們將選擇在有效的重定向URL部分中保留http:// localhost:8081/*。
Keycloak API:
您現在可能正在使用當前項目中的REST API。別擔心,Keycloak提供對REST API的完全支持。實際上,它還提供了一個完整的管理控制臺,可以通過REST API使用。
這是可能的Keycloak管理REST API列表。
對於管理REST API,有一個Java客戶端庫,可以很容易地與Java一起使用。要從您的應用程序中使用它 - 就像您對任何第三方庫所做的那樣 - 只需在項目中添加keycloak-admin-client庫的依賴項。而已。
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-admin-client</artifactId>
<version>3.2.1.Final</version>
</dependency>
application.yml配置:
server:
port: 9999
keycloak:
url: http://localhost:8080/auth
realm: master
username: admin
password: admin
clientId: admin-cli
註意:我們需要clientId作為admin-cli
,這由keycloak提供的所有默認客戶端ID,用於實現keycloak為admin提供的REST端點,
REST API實現
使用REST端點在域中創建用戶有幾個步驟:
1.創建用戶:
第1步:通過getInstance()方法使用主管理員的詳細信息創建實例
Keycloak kcMaster = Keycloak.getInstance(serverUrl, masterRealm, masterUsername, masterPassword, masterClientId);
第2步:在UserRepresentation中設置用戶數據
private String userName;
private String firstName;
private String lastName;
private String email;
private String password;
private String companyName;
密碼映射到CredentialRepresentation。您必須強制用戶在首次登錄時通過以下代碼更改密碼:
credential.setTemporary(isTempPassword);
and user.setRequiredActions(Arrays.asList(ACTION_UPDATE_PASSWORD));
最後,您所要做的就是在給定領域中調用createUser:
kcMaster.realm(request.getCompanyName()).users().create(user);
由於Keycloak擁有自己的數據庫,因此新創建的用戶信息存儲在表中:user_entity
恭喜!您剛剛使用REST端點在Keyclaok中創建了一個用戶。
2.用戶登錄訪問和刷新令牌
現在遇到一個重大挑戰:將用戶登錄到您的應用程序中
Keycloak根據您在Keycloak中配置客戶端的方式提供了幾種獲取訪問令牌的方法。Keycloak為您提供AccessTokenResponse,它是一個基於JWT的令牌,包含訪問令牌,刷新令牌和這些屬性的相關信息。
@PostMapping(path = "/login", consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE)
public AccessTokenResponse getToken(@RequestBody Map<String, Object> credentials) {
Keycloak kc = Keycloak.getInstance(serverUrl,
(String credentials.get("company"),
(String) credentials.get("username"),
(String) credentials.get("password"),
(String) credentials.get("clientId"));
return kc.tokenManager().getAccessToken();
}
您可以重新檢查詳細數據,該數據嵌入了jwt.io上的訪問令牌
Keycloak with Spring
Keycloak知道自己的API與應用程序的交互,並為願意與Keycloak通信的應用程序提供適配器。它已經為Javascript,NodeJs應用程序,WildFly / EAP和Spring Boot提供了適配器。Spring-boot的keycloak依賴(源代碼)
關於安全配置:
如果您是後端開發人員而且您正在使用Spring,並且您必須處理與安全相關的任務,那麽您肯定使用Spring Security。好吧,有一個好消息:有一個Keycloak Spring安全適配器,它包含在Spring Boot keycloak starter中。
如果您使用過Spring Security,那麽您可能知道SecurityConfig類擴展了WebSecurityConfigurerAdapter。這是為創建WebSecurityConfigurer實例提供了方便的基類,並且任何使用Spring Security的應用程序都需要它。Keycloak在WebSecurityConfigurerAdapter上提供了一個包裝類,名為KeycloakWebSecurityConfigurerAdapter。
現在讓我們看看如何將Spring Security和Keycloak結合在一起。
添加Spring Security Starter
首先,我們需要在pom.xml中添加spring-boot-starter-security工件來獲取Spring Security庫:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
創建SecurityConfig類
@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
@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();
}
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
@Override
protected void configure(HttpSecurity http) throws Exception
{
super.configure(http);
http
.authorizeRequests()
.antMatchers("/features*").hasRole("user")
.anyRequest().permitAll();
}
}
讓我們仔細看看最重要的方法:
- configureGlobal:如果你還記得Spring Security,那麽角色的前綴是ROLE_。這也可以在keycloak中完成,但這可能會導致其他應用程序不知道此約定的混淆。通過更改授權機構映射器,我們分配一個SimpleAuthorityMapper,確保不添加前綴。
- keycloakConfigResolver:默認情況下,Keycloak Spring Security Adapter將掃描類路徑中存在的名為keycloak.json的文件。在這裏,我們要提供Spring Boot屬性文件支持。
- configure:這是我們定義安全驗證的地方。很容易理解我們正在使用角色“user”保護路徑“/ features”。
結論
在您的應用程序中構建安全組件總是很困難,特別是當它是基於微服務的架構時。當然有多種選擇可用於構建安全服務,但Keycloak承擔這一責任並幫助開發人員專註於產品或應用程序所需的內容。
由於Keycloak中的每個組件都經過了很好的嘗試和測試,因此在安全模塊方面遇到任何麻煩的可能性都很小。
Keycloak確實為Spring開發人員提供了處理安全性的巨大潛力,特別是在開發正朝著構建微服務戰略的方向發展時。
使用Keycloak實現安全的SpringBoot微服務