bearer-tokens.adoc 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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. [tabs]
  10. ======
  11. Java::
  12. +
  13. [source,java,role="primary"]
  14. ----
  15. ServerBearerTokenAuthenticationConverter converter = new ServerBearerTokenAuthenticationConverter();
  16. converter.setBearerTokenHeaderName(HttpHeaders.PROXY_AUTHORIZATION);
  17. http
  18. .oauth2ResourceServer(oauth2 -> oauth2
  19. .bearerTokenConverter(converter)
  20. );
  21. ----
  22. Kotlin::
  23. +
  24. [source,kotlin,role="secondary"]
  25. ----
  26. val converter = ServerBearerTokenAuthenticationConverter()
  27. converter.setBearerTokenHeaderName(HttpHeaders.PROXY_AUTHORIZATION)
  28. return http {
  29. oauth2ResourceServer {
  30. bearerTokenConverter = converter
  31. }
  32. }
  33. ----
  34. ======
  35. == Bearer Token Propagation
  36. Now that you're in possession of a bearer token, it might be handy to pass that to downstream services.
  37. 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:
  38. [tabs]
  39. ======
  40. Java::
  41. +
  42. [source,java,role="primary"]
  43. ----
  44. @Bean
  45. public WebClient rest() {
  46. return WebClient.builder()
  47. .filter(new ServerBearerExchangeFilterFunction())
  48. .build();
  49. }
  50. ----
  51. Kotlin::
  52. +
  53. [source,kotlin,role="secondary"]
  54. ----
  55. @Bean
  56. fun rest(): WebClient {
  57. return WebClient.builder()
  58. .filter(ServerBearerExchangeFilterFunction())
  59. .build()
  60. }
  61. ----
  62. ======
  63. 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.
  64. Then, it will propagate that token in the `Authorization` header.
  65. For example:
  66. [tabs]
  67. ======
  68. Java::
  69. +
  70. [source,java,role="primary"]
  71. ----
  72. this.rest.get()
  73. .uri("https://other-service.example.com/endpoint")
  74. .retrieve()
  75. .bodyToMono(String.class)
  76. ----
  77. Kotlin::
  78. +
  79. [source,kotlin,role="secondary"]
  80. ----
  81. this.rest.get()
  82. .uri("https://other-service.example.com/endpoint")
  83. .retrieve()
  84. .bodyToMono<String>()
  85. ----
  86. ======
  87. Will invoke the `https://other-service.example.com/endpoint`, adding the bearer token `Authorization` header for you.
  88. In places where you need to override this behavior, it's a simple matter of supplying the header yourself, like so:
  89. [tabs]
  90. ======
  91. Java::
  92. +
  93. [source,java,role="primary"]
  94. ----
  95. this.rest.get()
  96. .uri("https://other-service.example.com/endpoint")
  97. .headers(headers -> headers.setBearerAuth(overridingToken))
  98. .retrieve()
  99. .bodyToMono(String.class)
  100. ----
  101. Kotlin::
  102. +
  103. [source,kotlin,role="secondary"]
  104. ----
  105. rest.get()
  106. .uri("https://other-service.example.com/endpoint")
  107. .headers { it.setBearerAuth(overridingToken) }
  108. .retrieve()
  109. .bodyToMono<String>()
  110. ----
  111. ======
  112. In this case, the filter will fall back and simply forward the request onto the rest of the web filter chain.
  113. [NOTE]
  114. 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.
  115. To obtain this level of support, please use the OAuth 2.0 Client filter.