Skip to content
Snippets Groups Projects
Commit 4e2126c5 authored by Johaney-s's avatar Johaney-s
Browse files

Add custom token exchange provider

parent 2d379072
No related branches found
No related tags found
1 merge request!4Add custom token exchange provider
Pipeline #19039 passed
......@@ -17,7 +17,6 @@ import org.slf4j.LoggerFactory;
import jakarta.ws.rs.core.Response;
import java.util.List;
import java.util.Map;
import static org.keycloak.authentication.authenticators.broker.AbstractIdpAuthenticator.BROKERED_CONTEXT_NOTE;
......
package cz.cesnet.keycloak;
import jakarta.ws.rs.core.Response;
import org.keycloak.OAuthErrorException;
import org.keycloak.events.Details;
import org.keycloak.events.Errors;
import org.keycloak.events.EventBuilder;
import org.keycloak.protocol.oidc.TokenExchangeContext;
import org.keycloak.protocol.oidc.TokenExchangeProvider;
import org.keycloak.protocol.oidc.DefaultTokenExchangeProvider;
import org.keycloak.jose.jws.JWSInput;
import org.keycloak.jose.jws.JWSInputException;
import org.keycloak.representations.JsonWebToken;
import org.keycloak.services.CorsErrorResponseException;
import org.keycloak.services.cors.Cors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CustomTokenExchangeProvider implements TokenExchangeProvider {
private static final Logger logger = LoggerFactory.getLogger(CustomTokenExchangeProvider.class);
@Override
public Response exchange(TokenExchangeContext context) {
logger.debug("Exchanging token by custom token exchange provider.");
EventBuilder event = context.getEvent();
JsonWebToken jwt;
Cors cors = context.getCors();
TokenExchangeContext.Params params = context.getParams();
String subjectToken = params.getSubjectToken();
try {
JWSInput jws = new JWSInput(subjectToken);
jwt = jws.readJsonContent(JsonWebToken.class);
} catch (JWSInputException e) {
event.detail(Details.REASON, "unable to parse jwt subject_token");
event.error(Errors.INVALID_TOKEN);
throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_TOKEN, "Invalid subject token", Response.Status.BAD_REQUEST);
}
String issuer = jwt.getIssuer();
logger.info("Token exchange issuer: {}", issuer);
logger.info(jwt.getOtherClaims().toString());
DefaultTokenExchangeProvider defaultTokenExchangeProvider = new DefaultTokenExchangeProvider();
return defaultTokenExchangeProvider.exchange(context);
}
@Override
public void close() {
}
@Override
public boolean supports(TokenExchangeContext context) {
return true;
}
}
\ No newline at end of file
package cz.cesnet.keycloak;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.keycloak.models.KeycloakSession;
import org.keycloak.protocol.oidc.TokenExchangeProvider;
import org.keycloak.protocol.oidc.TokenExchangeProviderFactory;
public class CustomTokenExchangeProviderFactory implements TokenExchangeProviderFactory {
private static final String PROVIDER_ID = "custom-token-exchange";
private static final Logger logger = LoggerFactory.getLogger(CustomTokenExchangeProviderFactory.class);
@Override
public TokenExchangeProvider create(KeycloakSession session) {
return new CustomTokenExchangeProvider();
}
@Override
public String getId() {
return PROVIDER_ID;
}
@Override
public void init(org.keycloak.Config.Scope config) {
}
@Override
public void postInit(org.keycloak.models.KeycloakSessionFactory factory) {
}
@Override
public void close() {
}
@Override
public int order() {
// important that this value is higher than the default TokenExchangeProvider, otherwise it won't use this one.
return 1000;
}
}
\ No newline at end of file
cz.cesnet.keycloak.CustomTokenExchangeProviderFactory
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment