+
Skip to content

Verification of external facebook token via "debug token" endpoint #40720

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 26, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@

import com.fasterxml.jackson.databind.JsonNode;

import jakarta.ws.rs.core.Response;
import org.keycloak.OAuth2Constants;
import org.keycloak.OAuthErrorException;
import org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider;
import org.keycloak.broker.oidc.mappers.AbstractJsonUserAttributeMapper;
import org.keycloak.broker.provider.BrokeredIdentityContext;
Expand All @@ -27,7 +30,11 @@
import org.keycloak.broker.social.SocialIdentityProvider;
import org.keycloak.events.EventBuilder;
import org.keycloak.models.KeycloakSession;
import org.keycloak.protocol.oidc.TokenExchangeContext;
import org.keycloak.saml.common.util.StringUtil;
import org.keycloak.services.ErrorResponseException;

import java.io.IOException;

/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
Expand All @@ -37,6 +44,7 @@ public class FacebookIdentityProvider extends AbstractOAuth2IdentityProvider<Fac
public static final String AUTH_URL = "https://graph.facebook.com/oauth/authorize";
public static final String TOKEN_URL = "https://graph.facebook.com/oauth/access_token";
public static final String PROFILE_URL = "https://graph.facebook.com/me?fields=id,name,email,first_name,last_name";
public static final String DEBUG_TOKEN_URL = "https://graph.facebook.com/debug_token";
public static final String DEFAULT_SCOPE = "email";
protected static final String PROFILE_URL_FIELDS_SEPARATOR = ",";

Expand All @@ -60,6 +68,29 @@ protected BrokeredIdentityContext doGetFederatedIdentity(String accessToken) {
}
}

private void verifyToken(String accessToken) throws IOException {
JsonNode response = SimpleHttp.doGet(DEBUG_TOKEN_URL, session)
.param("input_token", accessToken)
.param(OAuth2Constants.ACCESS_TOKEN, getConfig().getClientId() + "|" + getConfig().getClientSecret())
.asJson();

JsonNode errorNode = response.get("error");
if (errorNode != null) {
String errorMessage = getJsonProperty(errorNode, "message");
throw new RuntimeException("Error message: " + errorMessage);
}

JsonNode dataNode = response.get("data");
if (dataNode == null || dataNode.isNull()) {
throw new RuntimeException("Invalid token debug response: 'data' field is missing.");
}

String appId = getJsonProperty(dataNode, "app_id");
if (!getConfig().getClientId().equals(appId)) {
throw new RuntimeException("Client ID does not match the app_id in the access token debug response.");
}
}

@Override
protected boolean supportsExternalExchange() {
return true;
Expand Down Expand Up @@ -108,7 +139,22 @@ protected BrokeredIdentityContext extractIdentityFromProfile(EventBuilder event,
return user;
}

@Override
@Override
protected BrokeredIdentityContext exchangeExternalTokenV2Impl(TokenExchangeContext tokenExchangeContext) {
String subjectToken = tokenExchangeContext.getFormParams().getFirst(OAuth2Constants.SUBJECT_TOKEN);
if (subjectToken == null) {
throw new ErrorResponseException(OAuthErrorException.INVALID_TOKEN, "token not set", Response.Status.BAD_REQUEST);
}
try {
verifyToken(subjectToken);
return doGetFederatedIdentity(subjectToken);
}
catch (Exception e) {
throw new ErrorResponseException(OAuthErrorException.INVALID_TOKEN, e.getMessage(), Response.Status.BAD_REQUEST);
}
}

@Override
protected String getDefaultScopes() {
return DEFAULT_SCOPE;
}
Expand Down
Loading
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载