Skip to content

Commit

Permalink
feat(jans-keycloak-integration): enhancements to jans-keycloak-integr…
Browse files Browse the repository at this point in the history
…ation #8614

* moved authenticator rest service spi to spi module

Signed-off-by: Rolain Djeumen <uprightech@gmail.com>
  • Loading branch information
uprightech committed Jun 18, 2024
1 parent 4f453ab commit abf22ed
Show file tree
Hide file tree
Showing 2 changed files with 167 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package io.jans.kc.spi.rest;

import org.keycloak.forms.login.LoginFormsProvider;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.services.resource.RealmResourceProvider;

import io.jans.kc.spi.auth.SessionAttributes;

import java.util.Map;
import java.util.HashMap;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;

import org.jboss.logging.Logger;
import org.jboss.resteasy.annotations.cache.NoCache;

public class JansAuthResponseResourceProvider implements RealmResourceProvider {

private static final Logger log = Logger.getLogger(JansAuthResponseResourceProvider.class);

private static final String ACTION_URI_TPL_PARAM = "actionuri";
private static final String ERR_MSG_TPL_PARAM = "authError";

private static final String JANS_AUTH_RESPONSE_ERR_FTL ="jans-auth-response-error.ftl";
private static final String JANS_AUTH_RESPONSE_COMPLETE_FTL = "jans-auth-response-complete.ftl";

private static final String ERR_MSG_INVALID_REALM = "jans.error-invalid-realm";
private static final String ERR_MSG_MISSING_DATA = "jans.error-missing-data";

private KeycloakSession session;

public JansAuthResponseResourceProvider(KeycloakSession session) {

this.session = session;
}

@Override
public Object getResource() {

return this;
}

@Override
public void close() {

}

@GET
@NoCache
@Produces(MediaType.TEXT_HTML)
@Path("/auth-complete")
public Response completeAuthentication(@QueryParam("code") String code,
@QueryParam("scope") String scope,
@QueryParam("state") String state) {

RealmModel realm = getAuthenticationRealm();
if(!stateIsAssociatedToRealm(realm, state)) {
log.infov("Realm {0} is not associated to authz response and state {1}",realm.getName(),state);
return createErrorResponse(ERR_MSG_INVALID_REALM);
}

if(!realmHasActionUri(realm)) {
log.infov("Realm {0} has no action uri set to complete authentication",realm.getName());
return createErrorResponse(ERR_MSG_MISSING_DATA);
}
saveAuthResultInRealm(realm, code, state);
return createFinalizeAuthResponse(realm.getAttribute(SessionAttributes.KC_ACTION_URI));
}

private final RealmModel getAuthenticationRealm() {

return session.getContext().getRealm();
}

private final boolean stateIsAssociatedToRealm(RealmModel realm , String state) {

String expectedstate = realm.getAttribute(SessionAttributes.JANS_OIDC_STATE);

return state.equals(expectedstate);
}

private final boolean realmHasActionUri(RealmModel realm) {

String actionuri = realm.getAttribute(SessionAttributes.KC_ACTION_URI);
return (actionuri != null);
}

private final void saveAuthResultInRealm(RealmModel realm, String code, String session_state) {

realm.setAttribute(SessionAttributes.JANS_OIDC_CODE,code);
realm.setAttribute(SessionAttributes.JANS_SESSION_STATE,session_state);
}

private final Response createResponseWithForm(String formtemplate,Map<String,String> attributes) {

LoginFormsProvider lfp = session.getProvider(LoginFormsProvider.class);

if(attributes != null && !attributes.isEmpty()) {
for(String key: attributes.keySet()) {
lfp.setAttribute(key,attributes.get(key));
}
}
return lfp.createForm(formtemplate);
}

private final Response createErrorResponse(String errmsgid) {

Map<String,String> attributes = new HashMap<String,String>();
attributes.put(ERR_MSG_TPL_PARAM,errmsgid);
return createResponseWithForm(JANS_AUTH_RESPONSE_ERR_FTL,attributes);
}

private final Response createFinalizeAuthResponse(String actionuri) {

Map<String,String> attributes = new HashMap<String,String>();
attributes.put(ACTION_URI_TPL_PARAM,actionuri);
return createResponseWithForm(JANS_AUTH_RESPONSE_COMPLETE_FTL, attributes);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package io.jans.kc.spi.rest;

import org.keycloak.Config.Scope;

import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.services.resource.RealmResourceProvider;
import org.keycloak.services.resource.RealmResourceProviderFactory;

import io.jans.kc.spi.ProviderIDs;

public class JansAuthResponseResourceProviderFactory implements RealmResourceProviderFactory {

private static final String ID = ProviderIDs.JANS_AUTH_RESPONSE_REST_PROVIDER;

@Override
public String getId() {

return ID;
}

@Override
public RealmResourceProvider create(KeycloakSession session) {

return new JansAuthResponseResourceProvider(session);
}

@Override
public void init(Scope config) {

}

@Override
public void postInit(KeycloakSessionFactory factory) {

}

@Override
public void close() {

}
}

0 comments on commit abf22ed

Please sign in to comment.