基於springboot整合keycloak
Spring Boot Keycloak Starter依賴中已經包含了一個Keycloak Spring Security適配器。現在我們來看看如何將Spring Security和Keycloak集成。
1. 依賴
如果要在Spring Boot中使用Spring Security,我們必須添加這個依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
最新的Spring Boot Starter Security版本可以在 Maven Central找到。
2. 配置類
Keycloak提供了一個很方便的基類KeycloakWebSecurityConfigurerAdapter來創建WebSecurityConfigurer實例,因為任何由Spring Security保護的應用程序都需要一個配置類來擴展WebSecurityConfigurerAdapter:
package com.example.keycloakstudy.conf;
import org.keycloak.adapters.KeycloakConfigResolver;
import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
import org.keycloak.adapters.springsecurity.KeycloakSecurityComponents;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
@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:任務SimpleAuthorityMapper,以確保角色不以ROLE_為前綴
- keycloakConfigResolver:定義了我們想要使用的Spring Boot 屬性文件支持而不是默認的 keycloak.json
3. application.properties
因為已經用Spring Security設置了安全約束,所以我們可以刪除之前配置在application.properties中的相關配置。
現在我們將新增這個配置到application.properties中:
# 安全約束
#keycloak.securityConstraints[0].authRoles[0]=user
#keycloak.securityConstraints[0].securityCollections[0].name= common user
#keycloak.securityConstraints[0].securityCollections[0].patterns[0]=/products/*
keycloak.principal-attribute=preferred_username
4. 控制器
為了獲取到當前用戶的用戶名,我們需要在控制器注入Principal參數,修改后的代碼如下所示:
@GetMapping(path = "/products")
public String getProducts(Principal principal, Model model) {
model.addAttribute("principal", principal);
model.addAttribute("products", productService.getProducts());
return "product";
}
5. 修改product.ftl
在div標簽中,我們將添加一個問候語,如下所示:
<#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>
6. 運行
現在,通過認證和授權檢查后,頁面將跳轉到內部的customers頁面之后,我們將看到:
6 總結
在本教程中,我們配置了一個Keycloak服務器,並在Spring Boot應用程序中使用這個服務器。我們還看到了如何配置Spring Security,並將其與Keycloak服務器結合使用。