对于最新的稳定版本,请使用 Spring Security 6.3.1Spring中文文档

对于最新的稳定版本,请使用 Spring Security 6.3.1Spring中文文档

以下步骤与有关如何配置 OAuth 2.0 的更改相关。Spring中文文档

更改默认权限oauth2Login()

在 Spring Security 5 中,向使用 OAuth2 或 OpenID Connect 1.0 提供程序(通过 )进行身份验证的用户的默认值为 。GrantedAuthorityoauth2Login()ROLE_USERSpring中文文档

有关详细信息,请参阅映射用户权限Spring中文文档

在 Spring Security 6 中,授予使用 OAuth2 提供程序进行身份验证的用户的默认权限是 。 授予使用 OpenID Connect 1.0 提供程序进行身份验证的用户的默认权限是 。 通过这些默认值,可以更清楚地区分已通过 OAuth2 或 OpenID Connect 1.0 提供程序进行身份验证的用户。OAUTH2_USEROIDC_USERSpring中文文档

如果您使用授权规则或表达式(如 或)来授权具有此特定权限的用户,则 Spring Security 6 中的新默认值将影响您的应用程序。hasRole("USER")hasAuthority("ROLE_USER")Spring中文文档

要选择加入新的 Spring Security 6 默认值,可以使用以下配置。Spring中文文档

配置 oauth2Login() 默认值为 6.0
@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>

选择退出步骤

如果配置新授权程序会给您带来麻烦,您可以选择退出并显式使用以下配置的 5.8 授权程序。ROLE_USERSpring中文文档

配置 oauth2Login() 默认值为 5.8
@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>

有关详细信息,请参阅映射用户权限Spring中文文档

解决 OAuth2 客户端弃用问题

在 Spring Security 6 中,已从 OAuth2 客户端中删除了已弃用的类和方法。 下面列出了每个弃用,以及直接替换。Spring中文文档

ServletOAuth2AuthorizedClientExchangeFilterFunction

该方法可以替换为以下方法之一:setAccessTokenExpiresSkew(…​)Spring中文文档

该方法可以替换为构造函数。setClientCredentialsTokenResponseClient(…​)ServletOAuth2AuthorizedClientExchangeFilterFunction(OAuth2AuthorizedClientManager)Spring中文文档

有关详细信息,请参阅客户端凭据Spring中文文档

OidcUserInfo

该方法可以替换为 。phoneNumberVerified(String)phoneNumberVerified(Boolean)Spring中文文档

OAuth2AuthorizedClientArgumentResolver

该方法可以替换为构造函数。setClientCredentialsTokenResponseClient(…​)OAuth2AuthorizedClientArgumentResolver(OAuth2AuthorizedClientManager)Spring中文文档

有关详细信息,请参阅客户端凭据Spring中文文档

ClaimAccessor

该方法可以替换为 。containsClaim(…​)hasClaim(…​)Spring中文文档

OidcClientInitiatedLogoutSuccessHandler

该方法可以替换为 。setPostLogoutRedirectUri(URI)setPostLogoutRedirectUri(String)Spring中文文档

HttpSessionOAuth2AuthorizationRequestRepository

该方法没有直接替换。setAllowMultipleAuthorizationRequests(…​)Spring中文文档

AuthorizationRequestRepository

该方法可以替换为 。removeAuthorizationRequest(HttpServletRequest)removeAuthorizationRequest(HttpServletRequest, HttpServletResponse)Spring中文文档

ClientRegistration

该方法可以替换为 。getRedirectUriTemplate()getRedirectUri()Spring中文文档

ClientRegistration.Builder

该方法可以替换为 。redirectUriTemplate(…​)redirectUri(…​)Spring中文文档

AbstractOAuth2AuthorizationGrantRequest

构造函数可以替换为 。AbstractOAuth2AuthorizationGrantRequest(AuthorizationGrantType)AbstractOAuth2AuthorizationGrantRequest(AuthorizationGrantType, ClientRegistration)Spring中文文档

ClientAuthenticationMethod

静态字段可以替换为 。BASICCLIENT_SECRET_BASICSpring中文文档

静态字段可以替换为 。POSTCLIENT_SECRET_POSTSpring中文文档

OAuth2AccessTokenResponseHttpMessageConverter

该字段没有直接替换。tokenResponseConverterSpring中文文档

该方法可以替换为 。setTokenResponseConverter(…​)setAccessTokenResponseConverter(…​)Spring中文文档

该字段没有直接替换。tokenResponseParametersConverterSpring中文文档

该方法可以替换为 。setTokenResponseParametersConverter(…​)setAccessTokenResponseParametersConverter(…​)Spring中文文档

NimbusAuthorizationCodeTokenResponseClient

该类可以替换为 。NimbusAuthorizationCodeTokenResponseClientDefaultAuthorizationCodeTokenResponseClientSpring中文文档

NimbusJwtDecoderJwkSupport

该类可以替换为 或 。NimbusJwtDecoderJwkSupportNimbusJwtDecoderJwtDecodersSpring中文文档

ImplicitGrantConfigurer

该类没有直接替换。ImplicitGrantConfigurerSpring中文文档

不建议使用授权类型,并且在 Spring Security 6 中删除了所有相关支持。implicitSpring中文文档

AuthorizationGrantType

静态字段没有直接替换。IMPLICITSpring中文文档

不建议使用授权类型,并且在 Spring Security 6 中删除了所有相关支持。implicitSpring中文文档

OAuth2AuthorizationResponseType

静态字段没有直接替换。TOKENSpring中文文档

不建议使用授权类型,并且在 Spring Security 6 中删除了所有相关支持。implicitSpring中文文档

OAuth2AuthorizationRequest

静态方法没有直接替换。implicit()Spring中文文档

不建议使用授权类型,并且在 Spring Security 6 中删除了所有相关支持。implicitSpring中文文档

有关详细信息,请参阅客户端凭据Spring中文文档

有关详细信息,请参阅客户端凭据Spring中文文档

不建议使用授权类型,并且在 Spring Security 6 中删除了所有相关支持。implicitSpring中文文档

不建议使用授权类型,并且在 Spring Security 6 中删除了所有相关支持。implicitSpring中文文档

不建议使用授权类型,并且在 Spring Security 6 中删除了所有相关支持。implicitSpring中文文档

不建议使用授权类型,并且在 Spring Security 6 中删除了所有相关支持。implicitSpring中文文档

地址弃用JwtAuthenticationConverter

该方法将被删除。 而不是扩展 ,请提供带有 的自定义授权权限转换器。extractAuthoritiesJwtAuthenticationConverterJwtAuthenticationConverter#setJwtGrantedAuthoritiesConverterSpring中文文档