Keycloak是RedHat的開源身份和訪問管理解決方案,本文介紹如何在咱們的微服務安全模塊中使用keycloak,特別是基於SpringBoot的微服務。spring
它提供了身份和訪問管理的有用功能:數據庫
雖然安全性是任何應用程序的一個重要方面,但安全性的實現部分是複雜和困難的。一般,它在代碼中常常被忽略或執行不當和干擾。json
開發人員須要安全服務器,容許外包和受權認證和受權方面。他們想要一種可以自動開發應用程序安全功能的工具,這一般是一項複雜的任務。後端
Keycloak是最有前途的開源IDAM(身份和訪問管理)服務器之一,它與任何技術無關,能夠在本身的基礎架構中輕鬆部署/適應。瀏覽器
Keycloak嘗試解決基於REST的Web應用程序和Web服務的單點登陸。Keycloak的最終目標是使安全性足夠簡單,以便做爲服務和應用程序中的安全模塊插入。安全功能很混亂,當開發人員手動爲本身編寫時,它會變得更危險,更容易出錯。Keycloak經過提供開箱即用的安全功能幫助咱們,而且能夠根據任何組織的個性化需求輕鬆定製。安全
Keycloak能夠幫助咱們在應用程序中引入這些功能:服務器
有不一樣的方法來安裝keycloak。最簡單的是隻需下載Keycloak,這是一種獨立的安裝模式,只需將其解壓縮便可。你完成了!如今打開一個終端並轉到解壓縮的Keycloak服務器並導航到bin目錄 - 而後只需運行如下命令:session
./standalone.sh(bat)架構
安裝完成後,打開瀏覽器並轉到http:// localhost:8080 / auth。app
默認狀況下,Keycloak附帶一個H2數據庫,但若是你選擇RDMS,你可使用帶有RDMS的Keycloak。
因爲您是第一次運行服務器,所以您必須建立管理員用戶。讓咱們建立一個管理員用戶,其中「admin」做爲用戶名,「admin」做爲密碼。
在Keycloak中,領域是您定義客戶端的地方。這意味着這些客戶端是將由Keycloak保護的應用程序 - 多是Web應用程序或Spring Boot。
注意:'Master'是Keycloak的默認領域。讓咱們只需點擊「添加領域」按鈕便可建立新領域
Spring Boot應用程序是您的客戶端。就這麼簡單。在Keycloak中,客戶端是使用Keycloak保護的應用程序。
讓咱們看看如何在Keycloak中建立客戶端:
在下一個屏幕上將全部內容保持爲默認值,您須要的只是輸入一個有效的重定向URL,Keycloak將在該應用程序中對用戶進行身份驗證時使用該URL。咱們將選擇在有效的重定向URL部分中保留http:// localhost:8081/*。
您如今可能正在使用當前項目中的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端點在域中建立用戶有幾個步驟:
第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中建立了一個用戶。
如今遇到一個重大挑戰:將用戶登陸到您的應用程序中
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知道本身的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結合在一塊兒。
首先,咱們須要在pom.xml中添加spring-boot-starter-security工件來獲取Spring Security庫:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
@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(); } }
讓咱們仔細看看最重要的方法:
在您的應用程序中構建安全組件老是很困難,特別是當它是基於微服務的架構時。固然有多種選擇可用於構建安全服務,但Keycloak承擔這一責任並幫助開發人員專一於產品或應用程序所需的內容。
因爲Keycloak中的每一個組件都通過了很好的嘗試和測試,所以在安全模塊方面遇到任何麻煩的可能性都很小。
Keycloak確實爲Spring開發人員提供了處理安全性的巨大潛力,特別是在開發正朝着構建微服務戰略的方向發展時。