我正在尝试使用我的spring boot kotlin项目配置资源服务器,基本上我有一个不透明令牌的不记名令牌,我将其传递给来自移动应用程序的rest控制器,并且在服务器端我需要与网址为https://**.com/oauth2/token
的自定义授权服务器(opaquetoken)我当前的配置如下
application.yml
spring:
security:
oauth2:
resourceserver:
opaquetoken:
introspection-uri: https://****/oauth2/introspect
client-id: XXXX
client-secret: XXXX
和:
示例代码如下
@SpringBootApplication
class DemoApplication
@RestController
class HelloController {
@GetMapping("/hello")
fun hello(@AuthenticationPrincipal principal: OAuth2AuthenticatedPrincipal) = "hello ${principal.getAttribute<Any>("sub")}"
@GetMapping("/hello2")
fun hello2() = "hello2"
}
@Configuration
class WebSecurityConfigurerAdapter2 : WebSecurityConfigurerAdapter() {
@Value("\${spring.security.oauth2.resourceserver.opaque.introspection-uri}")
var introspectionUri: String? = null
@Value("\${spring.security.oauth2.resourceserver.opaque.client-id}")
var clientId: String? = null
@Value("\${spring.security.oauth2.resourceserver.opaque.client-secret}")
var clientSecret: String? = null
@Throws(Exception::class)
override fun configure(http: HttpSecurity) {
http
.authorizeRequests { authz ->
authz
.antMatchers("/hello")
.authenticated()
}
.oauth2ResourceServer { oauth2: OAuth2ResourceServerConfigurer<HttpSecurity?> ->
oauth2
.opaqueToken { token ->
val resourceDetails = ClientCredentialsResourceDetails()
resourceDetails.accessTokenUri = "https://****/oauth2/token"
resourceDetails.clientId = clientId
resourceDetails.clientSecret = clientSecret
resourceDetails.scope = listOf("***")
val restTemplate = OAuth2RestTemplate(resourceDetails)
token.introspector(NimbusOpaqueTokenIntrospector(introspectionUri, restTemplate))
}
}
}
}
fun main(args: Array<String>) {
runApplication<DemoApplication>(*args)
}
一切正常,在使用授权承载向承载GET
http://localhost:8080/hello
的承载令牌进行呼叫之后,我能够获取主体对象,但是我看到了ClientCredentialsResourceDetails
和OAuth2RestTemplate
已弃用,此自定义身份验证服务器是否有任何最新文档或示例代码,并内省休息。
感谢帮助和建议!
问题已解决- 和:
示例代码如下
@Component
类CustomRequestEntityConverter(
@Value(“ $ {spring.security.oauth2.resourceserver.opaquetoken.access-token-uri}”)val accessTokenUri:URI,
val属性:OAuth2ResourceServerProperties
):
Converter
private val restTemplate = RestTemplate()
override fun convert(token: String): RequestEntity<*>? {
val headers: HttpHeaders = requestHeaders(authToken())
val body: MultiValueMap<String, String> = requestBody(token)
return RequestEntity(
body,
headers,
HttpMethod.POST,
URI.create(properties.opaquetoken.introspectionUri)
)
}
/**
* Obtains auth-token from the Authentication server using client-credentials flow.
*/
private fun authToken(): String {
val headers = HttpHeaders()
headers.setBasicAuth(properties.opaquetoken.clientId, properties.opaquetoken.clientSecret)
headers.contentType = MediaType.APPLICATION_FORM_URLENCODED
val bodyParamMap = LinkedMultiValueMap<String, String>()
bodyParamMap.add("grant_type", "client_credentials");
val entity = HttpEntity<MultiValueMap<String, String>>(bodyParamMap, headers)
return restTemplate.postForObject(accessTokenUri, entity, JsonNode::class.java)
?.get("access_token")?.asText()
?: throw RuntimeException("Failed to retrieve access token from authentication server")
}
private fun requestHeaders(bearerToken: String): HttpHeaders {
val headers = HttpHeaders()
headers.setBearerAuth(bearerToken)
headers.accept = listOf(MediaType.APPLICATION_JSON)
return headers
}
private fun requestBody(token: String): MultiValueMap<String, String> {
val body: MultiValueMap<String, String> = LinkedMultiValueMap()
body.add("token", token)
return body
}
}
@配置 class WebSecurityConfigurerAdapter2:WebSecurityConfigurerAdapter(){
@Bean
fun opaqueTokenIntrospector(
properties: OAuth2ResourceServerProperties,
conv: CustomRequestEntityConverter
): NimbusOpaqueTokenIntrospector {
val introspector = NimbusOpaqueTokenIntrospector(
properties.opaquetoken.introspectionUri,
properties.opaquetoken.clientId,
properties.opaquetoken.clientSecret
)
introspector.setRequestEntityConverter(conv)
return introspector
}
override fun configure(http: HttpSecurity) {
http
.authorizeRequests { authz ->
authz
.antMatchers("/hello")
.authenticated()
}
.oauth2ResourceServer {
it
.opaqueToken()
}
}
}