You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Security OAuth集成LinkedIn API的认证异常问题排查

LinkedIn API与Spring Security OAuth集成异常问题

核心问题

  • 获取用户信息必须包含openid scope,但LinkedIn返回的是opaque token且未提供JWKs URI
  • Spring的OAuth2LoginAuthenticationProvider检测到openid scope后,会调用OidcAuthorizationCodeAuthenticationProvider,其内部createOidcToken方法需要查找JWKs URI,但LinkedIn不返回JWT,导致认证失败
  • 临时移除openid scope可正常运行,但业务需要该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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 01:10:56