基于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服务器结合使用。