使用 keycloak - JWT 令牌保护 Spring 引导服务
Securing Spring Boot service with keycloak - JWT token
所以,我正在使用 keycloak 来保护我的服务。客户端应用程序从 keycloak 服务器获取访问令牌,并使用它来保护对 Spring 启动应用程序的访问。我已经使用仅承载访问类型配置了我的 Spring 具有 keycloak 属性的启动应用程序:
keycloak.realm = master
keycloak.realmKey = ...
keycloak.auth-server-url = http://localhost:8080/auth
keycloak.ssl-required = external
keycloak.resource = boot-app
keycloak.bearer-only = true
keycloak.cors = true
Spring 启动 keycloak 启动器:
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
</dependency>
并配置 KeycloakWebSecurityConfigurerAdapter:
@Configuration
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
public class KeycloakSecurityConfig extends KeycloakWebSecurityConfigurerAdapter
{
/**
* Registers the KeycloakAuthenticationProvider with the authentication manager.
*/
@Autowired
public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception
{
final 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(final HttpSecurity http) throws Exception
{
super.configure(http);
http
.authorizeRequests()
.antMatchers(
"/v2/api-docs",
"/configuration/ui",
"/swagger-resources",
"/configuration/security",
"/swagger-ui.html",
"/webjars/**",
"/swagger-resources/configuration/ui",
"/swagger-ui.html",
"/swagger-resources/configuration/security").permitAll()
.antMatchers("/*").hasRole("user")
.anyRequest().authenticated();
}
}
现在,一切正常。我的问题是:不记名令牌是 JWT 令牌,您需要对其进行解码(并验证访问权限)的是 public 密钥,即
keycloak.realmKey
为什么需要其他设置,特别是:
keycloak.auth-server-url
public key 不是你需要的一切吗?
提前致谢
确实对于 bearer-only
你可能想知道为什么需要 KC URL 但由于一些 KC 版本 realmKey
不再是强制性的,因为我们使用密钥轮换。这意味着您的应用程序将使用 auth-server-url
属性 从 KC 服务器动态检索 public 密钥。
如果您有 spring-boot 应用程序,最新的 spring-security 会巧妙地处理它。您只需要在应用程序属性和所需的依赖项中定义 jwks-uri。
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http://localhost:8780/auth/realms/my-realm/protocol/openid-connect/certs
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-resource-server</artifactId>
<version>5.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
<version>5.3.3.RELEASE</version>
</dependency>
请注意,如果需要,您也可以使用颁发者 uri 而不是 jwks
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8780/auth/realms/my-realm
所以,我正在使用 keycloak 来保护我的服务。客户端应用程序从 keycloak 服务器获取访问令牌,并使用它来保护对 Spring 启动应用程序的访问。我已经使用仅承载访问类型配置了我的 Spring 具有 keycloak 属性的启动应用程序:
keycloak.realm = master
keycloak.realmKey = ...
keycloak.auth-server-url = http://localhost:8080/auth
keycloak.ssl-required = external
keycloak.resource = boot-app
keycloak.bearer-only = true
keycloak.cors = true
Spring 启动 keycloak 启动器:
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
</dependency>
并配置 KeycloakWebSecurityConfigurerAdapter:
@Configuration
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
public class KeycloakSecurityConfig extends KeycloakWebSecurityConfigurerAdapter
{
/**
* Registers the KeycloakAuthenticationProvider with the authentication manager.
*/
@Autowired
public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception
{
final 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(final HttpSecurity http) throws Exception
{
super.configure(http);
http
.authorizeRequests()
.antMatchers(
"/v2/api-docs",
"/configuration/ui",
"/swagger-resources",
"/configuration/security",
"/swagger-ui.html",
"/webjars/**",
"/swagger-resources/configuration/ui",
"/swagger-ui.html",
"/swagger-resources/configuration/security").permitAll()
.antMatchers("/*").hasRole("user")
.anyRequest().authenticated();
}
}
现在,一切正常。我的问题是:不记名令牌是 JWT 令牌,您需要对其进行解码(并验证访问权限)的是 public 密钥,即
keycloak.realmKey
为什么需要其他设置,特别是:
keycloak.auth-server-url
public key 不是你需要的一切吗?
提前致谢
确实对于 bearer-only
你可能想知道为什么需要 KC URL 但由于一些 KC 版本 realmKey
不再是强制性的,因为我们使用密钥轮换。这意味着您的应用程序将使用 auth-server-url
属性 从 KC 服务器动态检索 public 密钥。
如果您有 spring-boot 应用程序,最新的 spring-security 会巧妙地处理它。您只需要在应用程序属性和所需的依赖项中定义 jwks-uri。
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http://localhost:8780/auth/realms/my-realm/protocol/openid-connect/certs
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-resource-server</artifactId>
<version>5.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
<version>5.3.3.RELEASE</version>
</dependency>
请注意,如果需要,您也可以使用颁发者 uri 而不是 jwks
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8780/auth/realms/my-realm