按照你的身份提供方的流程操作,直到系统提示你指定 Redirect URI 为止。配置 Redirect URI 时,先选定一个 registrationId(例如
google、my-client,或任何你想用的唯一标识符),后续你将用它同时配置 Spring Security 和你的身份提供方。
Note
registrationId 是 Spring Security 中用于标识 ClientRegistration 的唯一标识符。默认的重定向 URI 模板为:{baseUrl}/login/oauth2/code/{registrationId}。更多信息请参阅 Spring Security 文档中的“设置重定向 URI”。
Tip
例如,在本地使用 9000 端口进行测试,且 registrationId 为 google 时,你的 Redirect URI 应为 localhost:9000/login/oauth2/code/google。配置应用到对应的 OAuth 提供商时,将该值填写为 Redirect URI。
一旦你完成了与社交登录提供商的配置流程,你应该已经拿到了凭证(Client ID 和 Client Secret)。此外,你还需要查阅该提供商的文档,并记录以下信息:
importjava.util.Arrays;importjava.util.Collections;importjava.util.HashMap;importjava.util.HashSet;importjava.util.Map;importjava.util.Set;importorg.springframework.security.core.Authentication;importorg.springframework.security.oauth2.core.oidc.IdTokenClaimNames;importorg.springframework.security.oauth2.core.oidc.OidcIdToken;importorg.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames;importorg.springframework.security.oauth2.core.oidc.user.OidcUser;importorg.springframework.security.oauth2.core.user.OAuth2User;importorg.springframework.security.oauth2.server.authorization.token.JwtEncodingContext;importorg.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer;publicfinalclassFederatedIdentityIdTokenCustomizerimplementsOAuth2TokenCustomizer<JwtEncodingContext>{privatestaticfinalSet<String>ID_TOKEN_CLAIMS=Collections.unmodifiableSet(newHashSet<>(Arrays.asList(IdTokenClaimNames.ISS,IdTokenClaimNames.SUB,IdTokenClaimNames.AUD,IdTokenClaimNames.EXP,IdTokenClaimNames.IAT,IdTokenClaimNames.AUTH_TIME,IdTokenClaimNames.NONCE,IdTokenClaimNames.ACR,IdTokenClaimNames.AMR,IdTokenClaimNames.AZP,IdTokenClaimNames.AT_HASH,IdTokenClaimNames.C_HASH)));@Overridepublicvoidcustomize(JwtEncodingContextcontext){if(OidcParameterNames.ID_TOKEN.equals(context.getTokenType().getValue())){Map<String,Object>thirdPartyClaims=extractClaims(context.getPrincipal());context.getClaims().claims(existingClaims->{// Remove conflicting claims set by this authorization serverexistingClaims.keySet().forEach(thirdPartyClaims::remove);// Remove standard id_token claims that could cause problems with clientsID_TOKEN_CLAIMS.forEach(thirdPartyClaims::remove);// Add all other claims directly to id_tokenexistingClaims.putAll(thirdPartyClaims);});}}privateMap<String,Object>extractClaims(Authenticationprincipal){Map<String,Object>claims;if(principal.getPrincipal()instanceofOidcUseroidcUser){OidcIdTokenidToken=oidcUser.getIdToken();claims=idToken.getClaims();}elseif(principal.getPrincipal()instanceofOAuth2Useroauth2User){claims=oauth2User.getAttributes();}else{claims=Collections.emptyMap();}returnnewHashMap<>(claims);}}
你可以将该自定义器通过发布为一个 @Bean 来配置到 Spring Authorization Server 中使用,如下例所示: