For the latest stable version, please use Spring Security 6.4.1!spring-doc.cn

OAuth Migrations

The following steps relate to changes around how to configure OAuth 2.0.spring-doc.cn

Change Default oauth2Login() Authorities

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.spring-doc.cn

See Mapping User Authorities for more information.spring-doc.cn

In Spring Security 6, the default authority given to a user authenticating with an OAuth2 provider is OAUTH2_USER. The default authority given to a user authenticating with an OpenID Connect 1.0 provider is OIDC_USER. These defaults allow clearer distinction of users that have authenticated with an OAuth2 or OpenID Connect 1.0 provider.spring-doc.cn

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.spring-doc.cn

To opt into the new Spring Security 6 defaults, the following configuration can be used.spring-doc.cn

Configure oauth2Login() with 6.0 defaults
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
	http
		// ...
		.oauth2Login((oauth2Login) -> oauth2Login
			.userInfoEndpoint((userInfo) -> userInfo
				.userAuthoritiesMapper(grantedAuthoritiesMapper())
			)
		);
	return http.build();
}

private GrantedAuthoritiesMapper grantedAuthoritiesMapper() {
	return (authorities) -> {
		Set<GrantedAuthority> mappedAuthorities = new HashSet<>();

		authorities.forEach((authority) -> {
			GrantedAuthority mappedAuthority;

			if (authority instanceof OidcUserAuthority) {
				OidcUserAuthority userAuthority = (OidcUserAuthority) authority;
				mappedAuthority = new OidcUserAuthority(
					"OIDC_USER", userAuthority.getIdToken(), userAuthority.getUserInfo());
			} else if (authority instanceof OAuth2UserAuthority) {
				OAuth2UserAuthority userAuthority = (OAuth2UserAuthority) authority;
				mappedAuthority = new OAuth2UserAuthority(
					"OAUTH2_USER", userAuthority.getAttributes());
			} else {
				mappedAuthority = authority;
			}

			mappedAuthorities.add(mappedAuthority);
		});

		return mappedAuthorities;
	};
}
@Bean
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
	http {
		// ...
		oauth2Login {
			userInfoEndpoint {
				userAuthoritiesMapper = grantedAuthoritiesMapper()
			}
		}
	}
	return http.build()
}

private fun grantedAuthoritiesMapper(): GrantedAuthoritiesMapper {
	return GrantedAuthoritiesMapper { authorities ->
		authorities.map { authority ->
			when (authority) {
				is OidcUserAuthority ->
					OidcUserAuthority("OIDC_USER", authority.idToken, authority.userInfo)
				is OAuth2UserAuthority ->
					OAuth2UserAuthority("OAUTH2_USER", authority.attributes)
				else -> authority
			}
		}
	}
}
<http>
	<oauth2-login user-authorities-mapper-ref="userAuthoritiesMapper" ... />
</http>

Opt-out Steps

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.spring-doc.cn

Configure oauth2Login() with 5.8 defaults
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
	http
		// ...
		.oauth2Login((oauth2Login) -> oauth2Login
			.userInfoEndpoint((userInfo) -> userInfo
				.userAuthoritiesMapper(grantedAuthoritiesMapper())
			)
		);
	return http.build();
}

private GrantedAuthoritiesMapper grantedAuthoritiesMapper() {
	return (authorities) -> {
		Set<GrantedAuthority> mappedAuthorities = new HashSet<>();

		authorities.forEach((authority) -> {
			GrantedAuthority mappedAuthority;

			if (authority instanceof OidcUserAuthority) {
				OidcUserAuthority userAuthority = (OidcUserAuthority) authority;
				mappedAuthority = new OidcUserAuthority(
					"ROLE_USER", userAuthority.getIdToken(), userAuthority.getUserInfo());
			} else if (authority instanceof OAuth2UserAuthority) {
				OAuth2UserAuthority userAuthority = (OAuth2UserAuthority) authority;
				mappedAuthority = new OAuth2UserAuthority(
					"ROLE_USER", userAuthority.getAttributes());
			} else {
				mappedAuthority = authority;
			}

			mappedAuthorities.add(mappedAuthority);
		});

		return mappedAuthorities;
	};
}
@Bean
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
	http {
		// ...
		oauth2Login {
			userInfoEndpoint {
				userAuthoritiesMapper = grantedAuthoritiesMapper()
			}
		}
	}
	return http.build()
}

private fun grantedAuthoritiesMapper(): GrantedAuthoritiesMapper {
	return GrantedAuthoritiesMapper { authorities ->
		authorities.map { authority ->
			when (authority) {
				is OidcUserAuthority ->
					OidcUserAuthority("ROLE_USER", authority.idToken, authority.userInfo)
				is OAuth2UserAuthority ->
					OAuth2UserAuthority("ROLE_USER", authority.attributes)
				else -> authority
			}
		}
	}
}
<http>
	<oauth2-login user-authorities-mapper-ref="userAuthoritiesMapper" ... />
</http>

Address OAuth2 Client Deprecations

In Spring Security 6, deprecated classes and methods were removed from OAuth2 Client. Each deprecation is listed below, along with a direct replacement.spring-doc.cn

ServletOAuth2AuthorizedClientExchangeFilterFunction

The method setAccessTokenExpiresSkew(…​) can be replaced with one of:spring-doc.cn

  • ClientCredentialsOAuth2AuthorizedClientProvider#setClockSkew(…​)spring-doc.cn

  • RefreshTokenOAuth2AuthorizedClientProvider#setClockSkew(…​)spring-doc.cn

  • JwtBearerOAuth2AuthorizedClientProvider#setClockSkew(…​)spring-doc.cn

The method setClientCredentialsTokenResponseClient(…​) can be replaced with the constructor ServletOAuth2AuthorizedClientExchangeFilterFunction(OAuth2AuthorizedClientManager).spring-doc.cn

See Client Credentials for more information.spring-doc.cn

OidcUserInfo

The method phoneNumberVerified(String) can be replaced with phoneNumberVerified(Boolean).spring-doc.cn

OAuth2AuthorizedClientArgumentResolver

The method setClientCredentialsTokenResponseClient(…​) can be replaced with the constructor OAuth2AuthorizedClientArgumentResolver(OAuth2AuthorizedClientManager).spring-doc.cn

See Client Credentials for more information.spring-doc.cn

ClaimAccessor

The method containsClaim(…​) can be replaced with hasClaim(…​).spring-doc.cn

OidcClientInitiatedLogoutSuccessHandler

The method setPostLogoutRedirectUri(URI) can be replaced with setPostLogoutRedirectUri(String).spring-doc.cn

HttpSessionOAuth2AuthorizationRequestRepository

The method setAllowMultipleAuthorizationRequests(…​) has no direct replacement.spring-doc.cn

AuthorizationRequestRepository

The method removeAuthorizationRequest(HttpServletRequest) can be replaced with removeAuthorizationRequest(HttpServletRequest, HttpServletResponse).spring-doc.cn

ClientRegistration

The method getRedirectUriTemplate() can be replaced with getRedirectUri().spring-doc.cn

ClientRegistration.Builder

The method redirectUriTemplate(…​) can be replaced with redirectUri(…​).spring-doc.cn

AbstractOAuth2AuthorizationGrantRequest

The constructor AbstractOAuth2AuthorizationGrantRequest(AuthorizationGrantType) can be replaced with AbstractOAuth2AuthorizationGrantRequest(AuthorizationGrantType, ClientRegistration).spring-doc.cn

ClientAuthenticationMethod

The static field BASIC can be replaced with CLIENT_SECRET_BASIC.spring-doc.cn

The static field POST can be replaced with CLIENT_SECRET_POST.spring-doc.cn

OAuth2AccessTokenResponseHttpMessageConverter

The field tokenResponseConverter has no direct replacement.spring-doc.cn

The method setTokenResponseConverter(…​) can be replaced with setAccessTokenResponseConverter(…​).spring-doc.cn

The field tokenResponseParametersConverter has no direct replacement.spring-doc.cn

The method setTokenResponseParametersConverter(…​) can be replaced with setAccessTokenResponseParametersConverter(…​).spring-doc.cn

NimbusAuthorizationCodeTokenResponseClient

The class NimbusAuthorizationCodeTokenResponseClient can be replaced with DefaultAuthorizationCodeTokenResponseClient.spring-doc.cn

NimbusJwtDecoderJwkSupport

The class NimbusJwtDecoderJwkSupport can be replaced with NimbusJwtDecoder or JwtDecoders.spring-doc.cn

ImplicitGrantConfigurer

The class ImplicitGrantConfigurer has no direct replacement.spring-doc.cn

Use of the implicit grant type is not recommended and all related support is removed in Spring Security 6.spring-doc.cn

AuthorizationGrantType

The static field IMPLICIT has no direct replacement.spring-doc.cn

Use of the implicit grant type is not recommended and all related support is removed in Spring Security 6.spring-doc.cn

OAuth2AuthorizationResponseType

The static field TOKEN has no direct replacement.spring-doc.cn

Use of the implicit grant type is not recommended and all related support is removed in Spring Security 6.spring-doc.cn

OAuth2AuthorizationRequest

The static method implicit() has no direct replacement.spring-doc.cn

Use of the implicit grant type is not recommended and all related support is removed in Spring Security 6.spring-doc.cn

Address JwtAuthenticationConverter Deprecation

The method extractAuthorities will be removed. Instead of extending JwtAuthenticationConverter, please supply a custom granted authorities converter with JwtAuthenticationConverter#setJwtGrantedAuthoritiesConverter.spring-doc.cn