gpt4 book ai didi

spring-boot - 资源服务器上的 Spring Boot OAuth2 自定义角色

转载 作者:行者123 更新时间:2023-12-03 12:24:21 26 4
gpt4 key购买 nike

TL;DR: 如何根据用户的 access_token 在资源服务器端(即没有 JWT)为用户分配自定义角色/权限?

全文:我有一个工作的 Auth 服务器和一个客户端(即 SPA),它可以从 Auth 服务器获取 access_token。使用该 access_token 客户端可以在我的资源服务器(与身份验证服务器分开)上请求数据。资源服务器可以使用 access_token 从 Auth 服务器获取用户名。

我可以通过注入(inject)访问代码中的用户名 Authentication对象变成这样的方法:

@RequestMapping("/ping")
fun pingPong(auth: Authentication): String = "pong, " + auth.name

我的问题是如何根据用户名将我的自定义角色或权限( auth.authorities - 只有 USER_ROLE)添加到将在资源服务器而不是身份验证服务器上管理的该对象。

我尝试了几种方法来做到这一点,但没有任何帮助。最有希望的是:

@Configuration
@EnableWebSecurity
@EnableResourceServer
class ResourceServerConfigurer(val userDetailsService: MyUserDetailsService) : ResourceServerConfigurerAdapter() {

override fun configure(http: HttpSecurity) {
http.userDetailsService(userDetailsService) // userDetailsService is autowired
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().authorizeRequests()
.antMatchers("/", "/index.html").permitAll()
.anyRequest().authenticated()
}
}

还有我的自定义 UserDetailsS​​ervice:

@Service
class UserDetailsService : org.springframework.security.core.userdetails.UserDetailsService {

override fun loadUserByUsername(username: String): UserDetails {
return org.springframework.security.core.userdetails.User(username, "password", getAuthorities(username))

}

private fun getAuthorities(user: String): Set<GrantedAuthority> {
val authorities = HashSet<GrantedAuthority>()
authorities.addAll(listOf(
SimpleGrantedAuthority("ROLE_ONE"), //let's grant some roles to everyone
SimpleGrantedAuthority("ROLE_TWO")))
return authorities
}
}

一切正常(我的意思是我已成功通过身份验证),除了我仍然只有 ROLE_USER。接下来我尝试的是提供 AbstractUserDetailsAuthenticationProvider 的自定义实现:

@Bean
fun authenticationProvider(): AbstractUserDetailsAuthenticationProvider {
return object : AbstractUserDetailsAuthenticationProvider() {
override fun retrieveUser(username: String, authentication: UsernamePasswordAuthenticationToken): UserDetails {
return User(username, "password", getAuthorities(username))

}

private fun getAuthorities(user: String): Set<GrantedAuthority> {
val authorities = HashSet<GrantedAuthority>()
authorities.addAll(listOf(
SimpleGrantedAuthority("ROLE_ONE"),
SimpleGrantedAuthority("ROLE_TWO")))
return authorities
}

override fun additionalAuthenticationChecks(userDetails: UserDetails, authentication: UsernamePasswordAuthenticationToken?) {
}
}
}

结果相同,只有 ROLE_USER 存在。

我真的很感谢你们在验证 access_token 并从 Auth 服务器获取用户名之后如何向 Authentication 对象添加一些角色的任何想法。

最佳答案

OP的解决方案。
首先我需要提供自定义 PrincipalExtractorAuthoritiesExtractor实现。但是要让 Spring 使用它们,配置中必须不要使用 security.oauth2.resource.token-info-uri但是 security.oauth2.resource.user-info-uri相反(我真的没想到这是我问题的根源之一)。
最后,安全配置必须在 ResourceServerConfigurerAdapter 中完成,不在 WebSecurityConfigurerAdapter 中.
最终代码如下所示:

    @SpringBootApplication
@RestController
class MyApplication {

@RequestMapping("/ping")
fun pingPong(user: Authentication): String {
return "pong, " + user.name + " - " + user.authorities.joinToString()
}
}

@Configuration
@EnableWebSecurity
@EnableResourceServer
class ResourceServerConfigurer : ResourceServerConfigurerAdapter() {

override fun configure(http: HttpSecurity) {
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().authorizeRequests()
.antMatchers("/", "/index.html").permitAll()
.anyRequest().authenticated()
}

@Bean
fun principalExtractor() = PrincipalExtractor {
return@PrincipalExtractor it["name"]
}

@Bean
fun authoritiesExtractor() = AuthoritiesExtractor {
return@AuthoritiesExtractor AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ONE,ROLE_TWO")
}
}

fun main(args: Array<String>) {
SpringApplication.run(MyApplication::class.java, *args)
}

关于spring-boot - 资源服务器上的 Spring Boot OAuth2 自定义角色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47618369/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com