oauth2.adoc 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. = OAuth Migrations
  2. The following steps relate to changes around how to configure OAuth 2.0.
  3. == Change Default `oauth2Login()` Authorities
  4. In Spring Security 5, the default `GrantedAuthority` given to a user that authenticates with an OAuth2 or OpenID Connect 1.0 provider (via `oauth2Login()`) is `ROLE_USER`.
  5. [NOTE]
  6. ====
  7. See xref:servlet/oauth2/login/advanced.adoc#oauth2login-advanced-map-authorities[Mapping User Authorities] for more information.
  8. ====
  9. In Spring Security 6, the default authority given to a user authenticating with an OAuth2 provider is `OAUTH2_USER`.
  10. The default authority given to a user authenticating with an OpenID Connect 1.0 provider is `OIDC_USER`.
  11. These defaults allow clearer distinction of users that have authenticated with an OAuth2 or OpenID Connect 1.0 provider.
  12. If you are using authorization rules or expressions such as `hasRole("USER")` or `hasAuthority("ROLE_USER")` to authorize users with this specific authority, the new defaults in Spring Security 6 will impact your application.
  13. To opt into the new Spring Security 6 defaults, the following configuration can be used.
  14. .Configure oauth2Login() with 6.0 defaults
  15. [tabs]
  16. ======
  17. Java::
  18. +
  19. [source,java,role="primary"]
  20. ----
  21. @Bean
  22. public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
  23. http
  24. // ...
  25. .oauth2Login((oauth2Login) -> oauth2Login
  26. .userInfoEndpoint((userInfo) -> userInfo
  27. .userAuthoritiesMapper(grantedAuthoritiesMapper())
  28. )
  29. );
  30. return http.build();
  31. }
  32. private GrantedAuthoritiesMapper grantedAuthoritiesMapper() {
  33. return (authorities) -> {
  34. Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
  35. authorities.forEach((authority) -> {
  36. GrantedAuthority mappedAuthority;
  37. if (authority instanceof OidcUserAuthority) {
  38. OidcUserAuthority userAuthority = (OidcUserAuthority) authority;
  39. mappedAuthority = new OidcUserAuthority(
  40. "OIDC_USER", userAuthority.getIdToken(), userAuthority.getUserInfo());
  41. } else if (authority instanceof OAuth2UserAuthority) {
  42. OAuth2UserAuthority userAuthority = (OAuth2UserAuthority) authority;
  43. mappedAuthority = new OAuth2UserAuthority(
  44. "OAUTH2_USER", userAuthority.getAttributes());
  45. } else {
  46. mappedAuthority = authority;
  47. }
  48. mappedAuthorities.add(mappedAuthority);
  49. });
  50. return mappedAuthorities;
  51. };
  52. }
  53. ----
  54. Kotlin::
  55. +
  56. [source,kotlin,role="secondary"]
  57. ----
  58. @Bean
  59. fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
  60. http {
  61. // ...
  62. oauth2Login {
  63. userInfoEndpoint {
  64. userAuthoritiesMapper = grantedAuthoritiesMapper()
  65. }
  66. }
  67. }
  68. return http.build()
  69. }
  70. private fun grantedAuthoritiesMapper(): GrantedAuthoritiesMapper {
  71. return GrantedAuthoritiesMapper { authorities ->
  72. authorities.map { authority ->
  73. when (authority) {
  74. is OidcUserAuthority ->
  75. OidcUserAuthority("OIDC_USER", authority.idToken, authority.userInfo)
  76. is OAuth2UserAuthority ->
  77. OAuth2UserAuthority("OAUTH2_USER", authority.attributes)
  78. else -> authority
  79. }
  80. }
  81. }
  82. }
  83. ----
  84. XML::
  85. +
  86. [source,xml,role="secondary"]
  87. ----
  88. <http>
  89. <oauth2-login user-authorities-mapper-ref="userAuthoritiesMapper" ... />
  90. </http>
  91. ----
  92. ======
  93. [[servlet-oauth2-login-authorities-opt-out]]
  94. === Opt-out Steps
  95. If configuring the new authorities gives you trouble, you can opt out and explicitly use the 5.8 authority of `ROLE_USER` with the following configuration.
  96. .Configure oauth2Login() with 5.8 defaults
  97. [tabs]
  98. ======
  99. Java::
  100. +
  101. [source,java,role="primary"]
  102. ----
  103. @Bean
  104. public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
  105. http
  106. // ...
  107. .oauth2Login((oauth2Login) -> oauth2Login
  108. .userInfoEndpoint((userInfo) -> userInfo
  109. .userAuthoritiesMapper(grantedAuthoritiesMapper())
  110. )
  111. );
  112. return http.build();
  113. }
  114. private GrantedAuthoritiesMapper grantedAuthoritiesMapper() {
  115. return (authorities) -> {
  116. Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
  117. authorities.forEach((authority) -> {
  118. GrantedAuthority mappedAuthority;
  119. if (authority instanceof OidcUserAuthority) {
  120. OidcUserAuthority userAuthority = (OidcUserAuthority) authority;
  121. mappedAuthority = new OidcUserAuthority(
  122. "ROLE_USER", userAuthority.getIdToken(), userAuthority.getUserInfo());
  123. } else if (authority instanceof OAuth2UserAuthority) {
  124. OAuth2UserAuthority userAuthority = (OAuth2UserAuthority) authority;
  125. mappedAuthority = new OAuth2UserAuthority(
  126. "ROLE_USER", userAuthority.getAttributes());
  127. } else {
  128. mappedAuthority = authority;
  129. }
  130. mappedAuthorities.add(mappedAuthority);
  131. });
  132. return mappedAuthorities;
  133. };
  134. }
  135. ----
  136. Kotlin::
  137. +
  138. [source,kotlin,role="secondary"]
  139. ----
  140. @Bean
  141. fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
  142. http {
  143. // ...
  144. oauth2Login {
  145. userInfoEndpoint {
  146. userAuthoritiesMapper = grantedAuthoritiesMapper()
  147. }
  148. }
  149. }
  150. return http.build()
  151. }
  152. private fun grantedAuthoritiesMapper(): GrantedAuthoritiesMapper {
  153. return GrantedAuthoritiesMapper { authorities ->
  154. authorities.map { authority ->
  155. when (authority) {
  156. is OidcUserAuthority ->
  157. OidcUserAuthority("ROLE_USER", authority.idToken, authority.userInfo)
  158. is OAuth2UserAuthority ->
  159. OAuth2UserAuthority("ROLE_USER", authority.attributes)
  160. else -> authority
  161. }
  162. }
  163. }
  164. }
  165. ----
  166. XML::
  167. +
  168. [source,xml,role="secondary"]
  169. ----
  170. <http>
  171. <oauth2-login user-authorities-mapper-ref="userAuthoritiesMapper" ... />
  172. </http>
  173. ----
  174. ======
  175. == Address OAuth2 Client Deprecations
  176. In Spring Security 6, deprecated classes and methods were removed from xref:servlet/oauth2/client/index.adoc[OAuth2 Client].
  177. Each deprecation is listed below, along with a direct replacement.
  178. === `ServletOAuth2AuthorizedClientExchangeFilterFunction`
  179. The method `setAccessTokenExpiresSkew(...)` can be replaced with one of:
  180. * `ClientCredentialsOAuth2AuthorizedClientProvider#setClockSkew(...)`
  181. * `RefreshTokenOAuth2AuthorizedClientProvider#setClockSkew(...)`
  182. * `JwtBearerOAuth2AuthorizedClientProvider#setClockSkew(...)`
  183. The method `setClientCredentialsTokenResponseClient(...)` can be replaced with the constructor `ServletOAuth2AuthorizedClientExchangeFilterFunction(OAuth2AuthorizedClientManager)`.
  184. [NOTE]
  185. ====
  186. See xref:servlet/oauth2/client/authorization-grants.adoc#oauth2Client-client-creds-grant[Client Credentials] for more information.
  187. ====
  188. === `OidcUserInfo`
  189. The method `phoneNumberVerified(String)` can be replaced with `phoneNumberVerified(Boolean)`.
  190. === `OAuth2AuthorizedClientArgumentResolver`
  191. The method `setClientCredentialsTokenResponseClient(...)` can be replaced with the constructor `OAuth2AuthorizedClientArgumentResolver(OAuth2AuthorizedClientManager)`.
  192. [NOTE]
  193. ====
  194. See xref:servlet/oauth2/client/authorization-grants.adoc#oauth2Client-client-creds-grant[Client Credentials] for more information.
  195. ====
  196. === `ClaimAccessor`
  197. The method `containsClaim(...)` can be replaced with `hasClaim(...)`.
  198. === `OidcClientInitiatedLogoutSuccessHandler`
  199. The method `setPostLogoutRedirectUri(URI)` can be replaced with `setPostLogoutRedirectUri(String)`.
  200. === `HttpSessionOAuth2AuthorizationRequestRepository`
  201. The method `setAllowMultipleAuthorizationRequests(...)` has no direct replacement.
  202. === `AuthorizationRequestRepository`
  203. The method `removeAuthorizationRequest(HttpServletRequest)` can be replaced with `removeAuthorizationRequest(HttpServletRequest, HttpServletResponse)`.
  204. === `ClientRegistration`
  205. The method `getRedirectUriTemplate()` can be replaced with `getRedirectUri()`.
  206. === `ClientRegistration.Builder`
  207. The method `redirectUriTemplate(...)` can be replaced with `redirectUri(...)`.
  208. === `AbstractOAuth2AuthorizationGrantRequest`
  209. The constructor `AbstractOAuth2AuthorizationGrantRequest(AuthorizationGrantType)` can be replaced with `AbstractOAuth2AuthorizationGrantRequest(AuthorizationGrantType, ClientRegistration)`.
  210. === `ClientAuthenticationMethod`
  211. The static field `BASIC` can be replaced with `CLIENT_SECRET_BASIC`.
  212. The static field `POST` can be replaced with `CLIENT_SECRET_POST`.
  213. === `OAuth2AccessTokenResponseHttpMessageConverter`
  214. The field `tokenResponseConverter` has no direct replacement.
  215. The method `setTokenResponseConverter(...)` can be replaced with `setAccessTokenResponseConverter(...)`.
  216. The field `tokenResponseParametersConverter` has no direct replacement.
  217. The method `setTokenResponseParametersConverter(...)` can be replaced with `setAccessTokenResponseParametersConverter(...)`.
  218. === `NimbusAuthorizationCodeTokenResponseClient`
  219. The class `NimbusAuthorizationCodeTokenResponseClient` can be replaced with `DefaultAuthorizationCodeTokenResponseClient`.
  220. === `NimbusJwtDecoderJwkSupport`
  221. The class `NimbusJwtDecoderJwkSupport` can be replaced with `NimbusJwtDecoder` or `JwtDecoders`.
  222. === `ImplicitGrantConfigurer`
  223. The class `ImplicitGrantConfigurer` has no direct replacement.
  224. [WARNING]
  225. ====
  226. Use of the `implicit` grant type is not recommended and all related support is removed in Spring Security 6.
  227. ====
  228. === `AuthorizationGrantType`
  229. The static field `IMPLICIT` has no direct replacement.
  230. [WARNING]
  231. ====
  232. Use of the `implicit` grant type is not recommended and all related support is removed in Spring Security 6.
  233. ====
  234. === `OAuth2AuthorizationResponseType`
  235. The static field `TOKEN` has no direct replacement.
  236. [WARNING]
  237. ====
  238. Use of the `implicit` grant type is not recommended and all related support is removed in Spring Security 6.
  239. ====
  240. === `OAuth2AuthorizationRequest`
  241. The static method `implicit()` has no direct replacement.
  242. [WARNING]
  243. ====
  244. Use of the `implicit` grant type is not recommended and all related support is removed in Spring Security 6.
  245. ====
  246. == Address `JwtAuthenticationConverter` Deprecation
  247. The method `extractAuthorities` will be removed.
  248. Instead of extending `JwtAuthenticationConverter`, please supply a custom granted authorities converter with `JwtAuthenticationConverter#setJwtGrantedAuthoritiesConverter`.