admin管理员组文章数量:1318564
I'm trying to integrate signup/login from linkedIn in my application which currently uses keycloak for authentication. I've implemented my flow in this way:
- My frontend redirects to linkedIn for sign in.
- LinkedIn then redirects to my callback in backend with authorization code.
- Then my backend application exchanges the code for access token and fetches userinfo from linkedIn and does necessary process.
- My backend manually creates a user in keycloak with federated identities set to linkedin.
- Invoke keycloaks token exchange api to exchange the token from LinkedIn with jwt from keycloak.
Here's an example code:
public JwtTokenResponse processOAuthCallbackAndGetToken(String code) {
// Step 1: Exchange authorization code for an access token
String accessToken = exchangeAuthorizationCodeForAccessToken(code);
// Step 2: Fetch user info from LinkedIn
Map<String, Object> userInfo = fetchLinkedInUserProfile(accessToken);
// Step 3: Create users in app
if (userInfo == null) {
throw new SomeException("Error occurred while fetching user info from LinkedIn.");
}
String email = (String) userInfo.get("email");
// create user in the application if needed
// Step 4: Create use in keycloak with federatedIdentity
log.info("User Info from LinkedIn ::: {}", userInfo);
Map<String, Object> federatedIdentity = new HashMap<>();
federatedIdentity.put("identityProvider", "linkedin");
federatedIdentity.put("userId", userInfo.get("sub")); // LinkedIn user ID
federatedIdentity.put("userName", email);
userService.createKeycloakUserWithFederatedIdentity(agentByEmail.getUser(), federatedIdentity);
log.info("Created user in keycloak with federated identity ::: {}", federatedIdentity);
// Step 5: Exchange LinkedIn access_token with jwt
return keycloakAuthServerConnector.getTokenFromLinkedInAccessToken(accessToken);
}
....
private static final String GRANT_TYPE_OAUTH_TOKEN_EXCHANGE =
"urn:ietf:params:oauth:grant-type:token-exchange";
private static final String REQUESTED_TOKEN_TYPE =
"urn:ietf:params:oauth:token-type:access_token";
public static final String PROTOCOL_OPENID_CONNECT_TOKEN = "/protocol/openid-connect/token";
public com.agencyheight.dto.onboardingv2.auth.JwtTokenResponse getTokenFromLinkedInAccessToken(
String accessToken) {
log.info("Requesting token with linkedIn access token :: {}", accessToken);
return webClient
.post()
.uri(PROTOCOL_OPENID_CONNECT_TOKEN)
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.body(
BodyInserters.fromFormData("client_id", clientId)
.with("client_secret", clientSecret)
.with("grant_type", GRANT_TYPE_OAUTH_TOKEN_EXCHANGE)
.with("subject_token", accessToken)
.with("subject_issuer", "linkedin")
.with("requested_token_type", REQUESTED_TOKEN_TYPE))
.retrieve()
.bodyToMono(com.agencyheight.dto.onboardingv2.auth.JwtTokenResponse.class)
.block();
}
I'm getting this response from keycloak when trying to exchange token. Status : 400 Bad Request
{
"error": "invalid_token",
"error_description": "invalid token"
}
I have added the necessary configuration in keycloak: I've enabled the token exchange permission as well and set the policy, as per this document : Granting permission for the exchange
What am I missing or what is causing the error?
I'm trying to integrate signup/login from linkedIn in my application which currently uses keycloak for authentication. I've implemented my flow in this way:
- My frontend redirects to linkedIn for sign in.
- LinkedIn then redirects to my callback in backend with authorization code.
- Then my backend application exchanges the code for access token and fetches userinfo from linkedIn and does necessary process.
- My backend manually creates a user in keycloak with federated identities set to linkedin.
- Invoke keycloaks token exchange api to exchange the token from LinkedIn with jwt from keycloak.
Here's an example code:
public JwtTokenResponse processOAuthCallbackAndGetToken(String code) {
// Step 1: Exchange authorization code for an access token
String accessToken = exchangeAuthorizationCodeForAccessToken(code);
// Step 2: Fetch user info from LinkedIn
Map<String, Object> userInfo = fetchLinkedInUserProfile(accessToken);
// Step 3: Create users in app
if (userInfo == null) {
throw new SomeException("Error occurred while fetching user info from LinkedIn.");
}
String email = (String) userInfo.get("email");
// create user in the application if needed
// Step 4: Create use in keycloak with federatedIdentity
log.info("User Info from LinkedIn ::: {}", userInfo);
Map<String, Object> federatedIdentity = new HashMap<>();
federatedIdentity.put("identityProvider", "linkedin");
federatedIdentity.put("userId", userInfo.get("sub")); // LinkedIn user ID
federatedIdentity.put("userName", email);
userService.createKeycloakUserWithFederatedIdentity(agentByEmail.getUser(), federatedIdentity);
log.info("Created user in keycloak with federated identity ::: {}", federatedIdentity);
// Step 5: Exchange LinkedIn access_token with jwt
return keycloakAuthServerConnector.getTokenFromLinkedInAccessToken(accessToken);
}
....
private static final String GRANT_TYPE_OAUTH_TOKEN_EXCHANGE =
"urn:ietf:params:oauth:grant-type:token-exchange";
private static final String REQUESTED_TOKEN_TYPE =
"urn:ietf:params:oauth:token-type:access_token";
public static final String PROTOCOL_OPENID_CONNECT_TOKEN = "/protocol/openid-connect/token";
public com.agencyheight.dto.onboardingv2.auth.JwtTokenResponse getTokenFromLinkedInAccessToken(
String accessToken) {
log.info("Requesting token with linkedIn access token :: {}", accessToken);
return webClient
.post()
.uri(PROTOCOL_OPENID_CONNECT_TOKEN)
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.body(
BodyInserters.fromFormData("client_id", clientId)
.with("client_secret", clientSecret)
.with("grant_type", GRANT_TYPE_OAUTH_TOKEN_EXCHANGE)
.with("subject_token", accessToken)
.with("subject_issuer", "linkedin")
.with("requested_token_type", REQUESTED_TOKEN_TYPE))
.retrieve()
.bodyToMono(com.agencyheight.dto.onboardingv2.auth.JwtTokenResponse.class)
.block();
}
I'm getting this response from keycloak when trying to exchange token. Status : 400 Bad Request
{
"error": "invalid_token",
"error_description": "invalid token"
}
I have added the necessary configuration in keycloak: I've enabled the token exchange permission as well and set the policy, as per this document : Granting permission for the exchange
What am I missing or what is causing the error?
Share Improve this question asked Jan 21 at 10:53 Sabu ShakyaSabu Shakya 3544 silver badges17 bronze badges1 Answer
Reset to default 0So the issue is that linkedIn's LinkedIn OpenID Connect, which provides opaque token, is supported only starting Keycloak's version 22 and greater New LinkedIn OpenID Connect social provider. I was using keycloak version 19 and worked on upgrading!
本文标签: javaLinkedIn access token exchange with keycloak tokenStack Overflow
版权声明:本文标题:java - LinkedIn access token exchange with keycloak token - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742048108a2417911.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论