
本文档阐述了如何在Spring OAuth2资源服务器中,针对特定端点实现自定义Token授权方案。重点介绍了利用JWT (JSON Web Token) 的方式,通过Keycloak配置,将自定义的授权信息添加到Token中,并在资源服务器端进行验证。同时,也探讨了使用客户端凭据流 (Client Credentials Flow) 为受信任的客户端进行授权的方法。
在标准的OAuth2流程中,资源服务器通常依赖于JWT中的信息进行授权。为了实现特定端点的自定义授权,我们可以利用Keycloak的mapper功能,将额外的授权信息添加到JWT中。
1. 在Keycloak中配置Mapper:
Keycloak的Mapper允许我们在用户登录时,将自定义的信息添加到access token中。例如,我们可以创建一个REST API来暴露订阅数据 (GET请求,返回给定用户订阅了什么,以及有效期至何时)。然后,在Keycloak中声明一个“confidential”客户端,使用client-credentials进行身份验证,并拥有访问此数据的专用角色。接下来,创建一个Keycloak mapper,在用户登录时查询此端点,并将返回的值作为私有声明添加到access token中。
参考示例项目: https://www.php.cn/link/68090119a695209306eefe7f69ebf574
2. 自定义AbstractAuthenticationToken:
在资源服务器端,我们需要创建一个自定义的AbstractAuthenticationToken实现,用于解析JWT中的自定义声明,并将其用于授权决策。这可以通过覆盖jwtAuthenticationConverter bean来实现,返回我们自定义的AbstractAuthenticationToken实现,而不是默认的JwtAuthenticationToken。
参考示例项目: https://www.php.cn/link/666108a9094a0ec0f62ca61a2eb74538
3. 使用@PreAuthorize进行授权:
有了自定义的AbstractAuthenticationToken,我们就可以在@PreAuthorize注解中使用自定义的表达式进行授权。例如:
@PreAuthorize("is(#username) or isNice() or onBehalfOf(#username).can('GREET')")其中,is(#username)、isNice()、onBehalfOf(#username).can('GREET')都是自定义的表达式,它们可以访问自定义AbstractAuthenticationToken中包含的信息,并进行授权决策。
对于不需要用户上下文的受信任客户端,我们可以使用Client Credentials Flow进行授权。
1. 在Keycloak中配置客户端:
在Keycloak中,为每个受信任的客户端声明一个“confidential”客户端,并启用client credentials。为这些客户端分配所需的角色。
2. 客户端获取Access Token:
客户端使用client credentials向授权服务器请求access token,并将access token作为Bearer authorization header发送给资源服务器。
3. 资源服务器验证Access Token:
从资源服务器的角度来看,所有请求都将使用相同的授权服务器颁发的access token进行授权,没有区别。
示例代码 (Spring Security配置):
@EnableWebSecurity
class WebSecurityConfiguration {
@Bean
fun filterChain(http: HttpSecurity): SecurityFilterChain {
http.authorizeRequests()
.antMatchers("/actuator/health").permitAll()
.antMatchers("/api/custom/players").access("hasAuthority('ROLE_PLAYERS')") // 使用角色进行授权
.antMatchers("/**").hasAnyRole("User", "Client")
.anyRequest().authenticated()
.and()
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(jwtAuthenticationConverter())
return http.build()
}
private fun jwtAuthenticationConverter(): Converter<Jwt?, out AbstractAuthenticationToken?> {
val jwtConverter = JwtAuthenticationConverter()
jwtConverter.setJwtGrantedAuthoritiesConverter(KeycloakRealmRoleConverter())
return jwtConverter
}
}注意事项:
总结:
通过结合Keycloak的Mapper功能和Spring Security的@PreAuthorize注解,我们可以实现灵活的自定义Token授权方案,满足不同场景下的授权需求。无论是基于用户上下文的授权,还是基于客户端凭据的授权,都可以通过本文介绍的方法来实现。
以上就是为Spring OAuth2资源服务器中的特定端点添加自定义Token授权的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号