anchor.diff:  }
   ----
   
  +.Kotlin
  +[source,kotlin,role="secondary"]
  +----
  +@Bean
  +fun rest(): RestTemplate {
  +    val rest = RestTemplate()
  +    rest.interceptors.add(ClientHttpRequestInterceptor { request, body, execution ->
  +        val authentication: Authentication? = SecurityContextHolder.getContext().authentication
  +        if (authentication != null) {
  +            execution.execute(request, body)
  +        }
  +
  +        if (authentication!!.credentials !is AbstractOAuth2Token) {
  +            execution.execute(request, body)
  +        }
  +
  +        val token: AbstractOAuth2Token = authentication.credentials as AbstractOAuth2Token
  +        request.headers.setBearerAuth(token.tokenValue)
  +        execution.execute(request, body)
  +    })
  +    return rest
  +}
  +----
  +====
  +
   
   [NOTE]
   Unlike the {security-api-url}org/springframework/security/oauth2/client/OAuth2AuthorizedClientManager.html[OAuth 2.0 Authorized Client Manager], this filter interceptor makes no attempt to renew the token, should it be expired.
  
positive.code: * Looks up the appropriate client registration associated with the `/userinfo` endpoint
  * Invokes and returns the response from the `/userinfo` endpoint
  
  [source,java]
  ----
  public class UserInfoOpaqueTokenIntrospector implements OpaqueTokenIntrospector {
      private final OpaqueTokenIntrospector delegate =
  
negative.code:     NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withJwkSetUri(jwkSetUri).restOperations(rest).build();
      return jwtDecoder;
  }
  ----
  
  .Kotlin
  [source,kotlin,role="secondary"]
  ----
  @Bean
  fun jwtDecoder(builder: RestTemplateBuilder): JwtDecoder {
      val rest: RestOperations = builder
              .setConnectTimeout(Duration.ofSeconds(60))
              .setReadTimeout(Duration.ofSeconds(60))
              .build()
      return NimbusJwtDecoder.withJwkSetUri(jwkSetUri).restOperations(rest).build()
  }
  ----
  ====
  
  Also by default, Resource Server caches in-memory the authorization server's JWK set for 5 minutes, which you may want to adjust.
  Further, it doesn't take into account more sophisticated caching patterns like eviction or using a shared cache.
  
  To adjust the way in which Resource Server caches the JWK set, `NimbusJwtDecoder` accepts an instance of `Cache`:
  
  ====
  .Java
  [source,java,role="primary"]
  ----
  @Bean
  public JwtDecoder jwtDecoder(CacheManager cacheManager) {
      return NimbusJwtDecoder.withJwkSetUri(jwkSetUri)
              .cache(cacheManager.getCache("jwks"))
              .build();
  }
  ----
  
  .Kotlin
  [source,kotlin,role="secondary"]
  ----
  @Bean
  fun jwtDecoder(cacheManager: CacheManager): JwtDecoder {
      return NimbusJwtDecoder.withJwkSetUri(jwkSetUri)
              .cache(cacheManager.getCache("jwks"))
              .build()
  }
  ----
  ====
  
  When given a `Cache`, Resource Server will use the JWK Set Uri as the key and the JWK Set JSON as the value.
  
  