如何使用自定义身份验证服务器为令牌配置资源服务器

时间:2020-10-03 20:47:47

标签: spring-security oauth-2.0 spring-security-oauth2

我正在尝试使用我的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的承载令牌进行呼叫之后,我能够获取主体对象,但是我看到了ClientCredentialsResourceDetailsOAuth2RestTemplate已弃用,此自定义身份验证服务器是否有任何最新文档或示例代码,并内省休息。

感谢帮助和建议!

问题已解决- 和:

示例代码如下

@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()
        }
}

}

0 个答案:

没有答案