I am trying to configure spring security to login with oauth2 for Facebook, Google and Linkedin. Facebook seems to be working fine so is google. But LinkedIn is giving me a hard time. I am getting this error:
[missing_signature_verifier] Failed to find a Signature Verifier for Client Registration: 'linkedin'. Check to ensure you have configured the JwkSet URI.
I went through other stackoverflow answers but none of the solutions helped. After going through as much stack overflow questions as I could, this is the code of my application currently:
application.yml
server:
port: 8081
spring:
security:
oauth2:
client:
registration:
linkedin:
clientId: ?
clientSecret: ?
scope: profile, email, openid
authorizationGrantType: authorization_code
redirect-uri: "https://0a47-2405-201-a805-7211-4d70-a5b5-611c-fa27.ngrok-free.app/login/oauth2/code/linkedin"
client-name: LinkedIn
clientAuthenticationMethod: client_secret_post
provider:
linkedin:
tokenUri: https://www.linkedin.com/oauth/v2/accessToken
authorizationUri: https://www.linkedin.com/oauth/v2/authorization
userInfoUri: https://api.linkedin.com/v2/userinfo
userNameAttribute: id
logging:
level:
org.springframework.security: TRACE
WebSecurityConfig.java
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
@Autowired
private ClientRegistrationRepository clientRegistrationRepository;
@Bean
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/login", "/resources/**", "/logout")
.permitAll()
.anyRequest().authenticated()
)
.oauth2Login(oauthLoginConfig -> oauthLoginConfig
.authorizationEndpoint((authorizationEndpointConfig ->
authorizationEndpointConfig.authorizationRequestResolver(
requestResolver(this.clientRegistrationRepository)
))
)
.tokenEndpoint(tokenEndpointConfig -> tokenEndpointConfig
.accessTokenResponseClient(linkedinTokenResponseClient())
)
);
return httpSecurity.build();
}
private static OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> 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;
}
private static DefaultOAuth2AuthorizationRequestResolver requestResolver
(ClientRegistrationRepository clientRegistrationRepository) {
DefaultOAuth2AuthorizationRequestResolver requestResolver =
new DefaultOAuth2AuthorizationRequestResolver(clientRegistrationRepository,
"/oauth2/authorization");
requestResolver.setAuthorizationRequestCustomizer(c ->
c.attributes(stringObjectMap -> stringObjectMap.remove(OidcParameterNames.NONCE))
.parameters(params -> params.remove(OidcParameterNames.NONCE))
);
return requestResolver;
}
}
Appreciate your help. Thanks in advance.
Rongon Phukan is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.