bearer-tokens.adoc 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. = OAuth 2.0 Resource Server Bearer Tokens
  2. [[webflux-oauth2resourceserver-bearertoken-resolver]]
  3. == Bearer Token Resolution
  4. By default, Resource Server looks for a bearer token in the `Authorization` header.
  5. This, however, can be customized.
  6. For example, you may have a need to read the bearer token from a custom header.
  7. To achieve this, you can wire an instance of `ServerBearerTokenAuthenticationConverter` into the DSL, as you can see in the following example:
  8. .Custom Bearer Token Header
  9. ====
  10. .Java
  11. [source,java,role="primary"]
  12. ----
  13. ServerBearerTokenAuthenticationConverter converter = new ServerBearerTokenAuthenticationConverter();
  14. converter.setBearerTokenHeaderName(HttpHeaders.PROXY_AUTHORIZATION);
  15. http
  16. .oauth2ResourceServer(oauth2 -> oauth2
  17. .bearerTokenConverter(converter)
  18. );
  19. ----
  20. .Kotlin
  21. [source,kotlin,role="secondary"]
  22. ----
  23. val converter = ServerBearerTokenAuthenticationConverter()
  24. converter.setBearerTokenHeaderName(HttpHeaders.PROXY_AUTHORIZATION)
  25. return http {
  26. oauth2ResourceServer {
  27. bearerTokenConverter = converter
  28. }
  29. }
  30. ----
  31. ====
  32. == Bearer Token Propagation
  33. Now that you're in possession of a bearer token, it might be handy to pass that to downstream services.
  34. This is quite simple with `{security-api-url}org/springframework/security/oauth2/server/resource/web/reactive/function/client/ServerBearerExchangeFilterFunction.html[ServerBearerExchangeFilterFunction]`, which you can see in the following example:
  35. ====
  36. .Java
  37. [source,java,role="primary"]
  38. ----
  39. @Bean
  40. public WebClient rest() {
  41. return WebClient.builder()
  42. .filter(new ServerBearerExchangeFilterFunction())
  43. .build();
  44. }
  45. ----
  46. .Kotlin
  47. [source,kotlin,role="secondary"]
  48. ----
  49. @Bean
  50. fun rest(): WebClient {
  51. return WebClient.builder()
  52. .filter(ServerBearerExchangeFilterFunction())
  53. .build()
  54. }
  55. ----
  56. ====
  57. When the above `WebClient` is used to perform requests, Spring Security will look up the current `Authentication` and extract any `{security-api-url}org/springframework/security/oauth2/core/AbstractOAuth2Token.html[AbstractOAuth2Token]` credential.
  58. Then, it will propagate that token in the `Authorization` header.
  59. For example:
  60. ====
  61. .Java
  62. [source,java,role="primary"]
  63. ----
  64. this.rest.get()
  65. .uri("https://other-service.example.com/endpoint")
  66. .retrieve()
  67. .bodyToMono(String.class)
  68. ----
  69. .Kotlin
  70. [source,kotlin,role="secondary"]
  71. ----
  72. this.rest.get()
  73. .uri("https://other-service.example.com/endpoint")
  74. .retrieve()
  75. .bodyToMono<String>()
  76. ----
  77. ====
  78. Will invoke the `https://other-service.example.com/endpoint`, adding the bearer token `Authorization` header for you.
  79. In places where you need to override this behavior, it's a simple matter of supplying the header yourself, like so:
  80. ====
  81. .Java
  82. [source,java,role="primary"]
  83. ----
  84. this.rest.get()
  85. .uri("https://other-service.example.com/endpoint")
  86. .headers(headers -> headers.setBearerAuth(overridingToken))
  87. .retrieve()
  88. .bodyToMono(String.class)
  89. ----
  90. .Kotlin
  91. [source,kotlin,role="secondary"]
  92. ----
  93. rest.get()
  94. .uri("https://other-service.example.com/endpoint")
  95. .headers { it.setBearerAuth(overridingToken) }
  96. .retrieve()
  97. .bodyToMono<String>()
  98. ----
  99. ====
  100. In this case, the filter will fall back and simply forward the request onto the rest of the web filter chain.
  101. [NOTE]
  102. Unlike the https://docs.spring.io/spring-security/site/docs/current-SNAPSHOT/api/org/springframework/security/oauth2/client/web/reactive/function/client/ServerOAuth2AuthorizedClientExchangeFilterFunction.html[OAuth 2.0 Client filter function], this filter function makes no attempt to renew the token, should it be expired.
  103. To obtain this level of support, please use the OAuth 2.0 Client filter.