Spring Security OAuth集成LinkedIn API的认证异常问题排查
LinkedIn API与Spring Security OAuth集成异常问题
核心问题
- 获取用户信息必须包含
openidscope,但LinkedIn返回的是opaque token且未提供JWKs URI - Spring的
OAuth2LoginAuthenticationProvider检测到openidscope后,会调用OidcAuthorizationCodeAuthenticationProvider,其内部createOidcToken方法需要查找JWKs URI,但LinkedIn不返回JWT,导致认证失败 - 临时移除
openidscope可正常运行,但业务需要该scope - 尝试自定义
AuthenticationProvider(复制官方OAuth2LoginAuthenticationProvider并删除第98-105行),但Spring无法注入依赖
application.yml 配置
spring: security: oauth2: client: registration: linkedin: provider: linkedin client-id: ${LINKEDIN_CLIENT_ID} client-secret: ${LINKEDIN_CLIENT_SECRET} client-authentication-method: client_secret_post authorization-grant-type: 'authorization_code' redirect-uri: '{baseUrl}/login/oauth2/code/linkedin' scope: - profile - email - openid provider: linkedin: authorization-uri: https://www.linkedin.com/oauth/v2/authorization token-uri: https://www.linkedin.com/oauth/v2/accessToken user-info-uri: https://api.linkedin.com/v2/userinfo user-name-attribute: sub
安全配置类代码
@Bean @Order(2) public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity httpSecurity) throws Exception { httpSecurity .authorizeHttpRequests((authorize) -> authorize .requestMatchers("/login", "/resources/**", "/logout") .permitAll() .anyRequest().authenticated() ) .oauth2Login(oauthLoginConfig -> oauthLoginConfig .tokenEndpoint(tokenEndpointConfig -> { tokenEndpointConfig.accessTokenResponseClient(linkedinTokenResponseClient()); })); return httpSecurity.build(); } private static DefaultAuthorizationCodeTokenResponseClient linkedinTokenResponseClient() { var defaultMapConverter = new DefaultMapOAuth2AccessTokenResponseConverter(); Converter<Map<String, Object>, OAuth2AccessTokenResponse> linkedinMapConverter = tokenResponse -> { var withTokenType = new HashMap<>(tokenResponse); withTokenType.put(OAuth2ParameterNames.TOKEN_TYPE, OAuth2AccessToken.TokenType.BEARER.getValue()); return defaultMapConverter.convert(withTokenType); }; var httpConverter = new OAuth2AccessTokenResponseHttpMessageConverter(); httpConverter.setAccessTokenResponseConverter(linkedinMapConverter); var restOperations = new RestTemplate(List.of(new FormHttpMessageConverter(), httpConverter)); restOperations.setErrorHandler(new OAuth2ErrorResponseErrorHandler()); var client = new DefaultAuthorizationCodeTokenResponseClient(); client.setRestOperations(restOperations); return client; }
自定义AuthenticationProvider说明
完全复制Spring Security官方的OAuth2LoginAuthenticationProvider实现,仅删除了第98至105行的代码,但Spring无法完成该自定义类的依赖注入。
内容的提问来源于stack exchange,提问作者Aman Desai
相关产品推荐
相关产品推荐

