Skip to content
Snippets Groups Projects
Commit 272e7a63 authored by Johana Balčiráková's avatar Johana Balčiráková
Browse files

Merge branch 'exchangeCheck' into 'main'

Add custom token exchange provider

See merge request !4
parents d30dc922 4e2126c5
No related branches found
No related tags found
1 merge request!4Add custom token exchange provider
Pipeline #20857 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