Keycloak
集成 Spring Security
之前,Spring Security OAuth 协议栈提供了将授权服务器设置为 Spring 应用的可能性。然后,我们必须将其配置为使用 JwtTokenStore,这样我们就可以使用 JWT 令牌。然而,OAuth 协议栈已经被 Spring 废弃,现在我们将使用 Keycloak 作为我们的授权服务器。所以这次,我们将把我们的授权服务器设置为 Spring Boot 应用中的嵌入式 Keycloak 服务器。它默认会发出 JWT 令牌,所以在这方面不需要任何其他配置。
Resource Server
首先在 application.yml 中进行如下定义:
server:
port: 8081
servlet:
context-path: /resource-server
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: http://localhost:8083/auth/realms/baeldung
jwk-set-uri: http://localhost:8083/auth/realms/baeldung/protocol/openid-connect/certs
JWTs 包括 Token 内的所有信息。因此,资源服务器需要验证 Token 的签名,以确保数据没有被修改。jwk-set-uri 属性包含了服务器可用于此目的的公钥。issuer-uri 属性指向基础授权服务器的 URI,它也可以用来验证 iss 声明,作为一种额外的安全措施。
此外,如果没有设置 jwk-set-uri 属性,资源服务器将尝试使用 issuer-ui 从授权服务器元数据端点确定该密钥的位置。重要的是,添加 issuer-uri 属性强制要求我们在启动 Resource Server 应用程序之前,应该先让 Authorization Server 运行。现在让我们看看如何使用 Java 配置来配置 JWT 支持。
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors()
.and()
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/user/info", "/api/foos/**")
.hasAuthority("SCOPE_read")
.antMatchers(HttpMethod.POST, "/api/foos")
.hasAuthority("SCOPE_write")
.anyRequest()
.authenticated()
.and()
.oauth2ResourceServer()
.jwt();
}
}
在这里,我们覆盖了默认的 Http 安全配置。因此,我们需要明确地指定,我们希望这是个资源服务器,并且我们将分别使用 oauth2ResourceServer()和 jwt()方法来使用 JWT 格式的访问令牌。上面的 JWT 配置是默认的 Spring Boot 实例为我们提供的。这也可以被定制,我们很快就会看到。
Custom Claims in the Token
现在让我们设置一些基础设施,以便能够在授权服务器返回的访问令牌中添加一些自定义声明。框架提供的标准声明都是很好的,但大多数时候我们需要在令牌中添加一些额外的信息,以便在客户端使用。
让我们举一个自定义声明的例子,组织,它将包含一个给定用户的组织名称。
Authorization Server Configuration
为此,我们需要在域定义文件 baeldung-realm.json 中添加一些配置: