commit
e55eb73fb9
2 changed files with 46 additions and 30 deletions
|
@ -11,6 +11,7 @@ import org.apache.catalina.Valve;
|
|||
import org.apache.catalina.connector.Request;
|
||||
import org.apache.catalina.connector.Response;
|
||||
import org.apache.catalina.valves.ValveBase;
|
||||
import org.keycloak.adapters.AdapterDeploymentContext;
|
||||
import org.keycloak.adapters.AuthenticatedActionsHandler;
|
||||
import org.keycloak.adapters.KeycloakDeployment;
|
||||
|
||||
|
@ -27,10 +28,10 @@ import org.keycloak.adapters.KeycloakDeployment;
|
|||
*/
|
||||
public class AuthenticatedActionsValve extends ValveBase {
|
||||
private static final Logger log = Logger.getLogger(""+AuthenticatedActionsValve.class);
|
||||
protected KeycloakDeployment deployment;
|
||||
protected AdapterDeploymentContext deploymentContext;
|
||||
|
||||
public AuthenticatedActionsValve(KeycloakDeployment deployment, Valve next, Container container, ObjectName objectName) {
|
||||
this.deployment = deployment;
|
||||
public AuthenticatedActionsValve(AdapterDeploymentContext deploymentContext, Valve next, Container container, ObjectName controller) {
|
||||
this.deploymentContext = deploymentContext;
|
||||
if (next == null) throw new RuntimeException("WTF is next null?!");
|
||||
setNext(next);
|
||||
setContainer(container);
|
||||
|
@ -40,10 +41,17 @@ public class AuthenticatedActionsValve extends ValveBase {
|
|||
@Override
|
||||
public void invoke(Request request, Response response) throws IOException, ServletException {
|
||||
log.finer("AuthenticatedActionsValve.invoke" + request.getRequestURI());
|
||||
AuthenticatedActionsHandler handler = new AuthenticatedActionsHandler(deployment, new CatalinaHttpFacade(request, response));
|
||||
if (handler.handledRequest()) {
|
||||
return;
|
||||
CatalinaHttpFacade facade = new CatalinaHttpFacade(request, response);
|
||||
KeycloakDeployment deployment = deploymentContext.resolveDeployment(facade);
|
||||
if (deployment != null && deployment.isConfigured()) {
|
||||
AuthenticatedActionsHandler handler = new AuthenticatedActionsHandler(deployment, new CatalinaHttpFacade(request, response));
|
||||
if (handler.handledRequest()) {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
getNext().invoke(request, response);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -23,8 +23,10 @@ import org.apache.catalina.core.StandardContext;
|
|||
import org.apache.catalina.deploy.LoginConfig;
|
||||
import org.keycloak.KeycloakSecurityContext;
|
||||
import org.keycloak.adapters.AdapterConstants;
|
||||
import org.keycloak.adapters.AdapterDeploymentContext;
|
||||
import org.keycloak.adapters.AuthChallenge;
|
||||
import org.keycloak.adapters.AuthOutcome;
|
||||
import org.keycloak.adapters.HttpFacade;
|
||||
import org.keycloak.adapters.KeycloakDeployment;
|
||||
import org.keycloak.adapters.KeycloakDeploymentBuilder;
|
||||
import org.keycloak.adapters.PreAuthActionsHandler;
|
||||
|
@ -43,7 +45,7 @@ import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
|
|||
public class KeycloakAuthenticatorValve extends FormAuthenticator implements LifecycleListener {
|
||||
private final static Logger log = Logger.getLogger(""+KeycloakAuthenticatorValve.class);
|
||||
protected CatalinaUserSessionManagement userSessionManagement = new CatalinaUserSessionManagement();
|
||||
protected KeycloakDeployment deployment;
|
||||
protected AdapterDeploymentContext deploymentContext;
|
||||
|
||||
@Override
|
||||
public void lifecycleEvent(LifecycleEvent event) {
|
||||
|
@ -64,9 +66,17 @@ public class KeycloakAuthenticatorValve extends FormAuthenticator implements Lif
|
|||
}
|
||||
|
||||
public void initInternal() {
|
||||
this.deployment = KeycloakDeploymentBuilder.build(getConfigInputStream(context));
|
||||
log.info("deployment realm:" + deployment.getRealm() + " resource:" + deployment.getResourceName());
|
||||
AuthenticatedActionsValve actions = new AuthenticatedActionsValve(deployment, getNext(), getContainer(), getObjectName());
|
||||
InputStream configInputStream = getConfigInputStream(context);
|
||||
KeycloakDeployment kd = null;
|
||||
if (configInputStream == null) {
|
||||
log.warning("No adapter configuration. Keycloak is unconfigured and will deny all requests.");
|
||||
kd = new KeycloakDeployment();
|
||||
} else {
|
||||
kd = KeycloakDeploymentBuilder.build(configInputStream);
|
||||
}
|
||||
deploymentContext = new AdapterDeploymentContext(kd);
|
||||
context.getServletContext().setAttribute(AdapterDeploymentContext.class.getName(), deploymentContext);
|
||||
AuthenticatedActionsValve actions = new AuthenticatedActionsValve(deploymentContext, getNext(), getContainer(), getObjectName());
|
||||
setNext(actions);
|
||||
}
|
||||
|
||||
|
@ -102,12 +112,12 @@ public class KeycloakAuthenticatorValve extends FormAuthenticator implements Lif
|
|||
@Override
|
||||
public void invoke(Request request, Response response) throws IOException, ServletException {
|
||||
try {
|
||||
PreAuthActionsHandler handler = new PreAuthActionsHandler(userSessionManagement, deployment,
|
||||
new CatalinaHttpFacade(request, response));
|
||||
CatalinaHttpFacade facade = new CatalinaHttpFacade(request, response);
|
||||
PreAuthActionsHandler handler = new PreAuthActionsHandler(userSessionManagement, deploymentContext, facade);
|
||||
if (handler.handleRequest()) {
|
||||
return;
|
||||
}
|
||||
checkKeycloakSession(request);
|
||||
checkKeycloakSession(request, facade);
|
||||
super.invoke(request, response);
|
||||
} finally {
|
||||
}
|
||||
|
@ -116,6 +126,11 @@ public class KeycloakAuthenticatorValve extends FormAuthenticator implements Lif
|
|||
@Override
|
||||
public boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws IOException {
|
||||
CatalinaHttpFacade facade = new CatalinaHttpFacade(request, response);
|
||||
KeycloakDeployment deployment = deploymentContext.resolveDeployment(facade);
|
||||
if (deployment == null || !deployment.isConfigured()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CatalinaRequestAuthenticator authenticator = new CatalinaRequestAuthenticator(deployment, this, userSessionManagement, facade, request);
|
||||
AuthOutcome outcome = authenticator.authenticate();
|
||||
if (outcome == AuthOutcome.AUTHENTICATED) {
|
||||
|
@ -132,29 +147,22 @@ public class KeycloakAuthenticatorValve extends FormAuthenticator implements Lif
|
|||
}
|
||||
|
||||
/**
|
||||
* Checks that access token is still valid. Will attempt refresh of token if
|
||||
* it is not.
|
||||
*
|
||||
* Checks that access token is still valid. Will attempt refresh of token if it is not.
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
protected void checkKeycloakSession(Request request) {
|
||||
if (request.getSessionInternal(false) == null || request.getSessionInternal().getPrincipal() == null)
|
||||
return;
|
||||
RefreshableKeycloakSecurityContext session = (RefreshableKeycloakSecurityContext) request.getSessionInternal()
|
||||
.getNote(KeycloakSecurityContext.class.getName());
|
||||
if (session == null)
|
||||
return;
|
||||
protected void checkKeycloakSession(Request request, HttpFacade facade) {
|
||||
if (request.getSessionInternal(false) == null || request.getSessionInternal().getPrincipal() == null) return;
|
||||
RefreshableKeycloakSecurityContext session = (RefreshableKeycloakSecurityContext) request.getSessionInternal().getNote(KeycloakSecurityContext.class.getName());
|
||||
if (session == null) return;
|
||||
// just in case session got serialized
|
||||
session.setDeployment(deployment);
|
||||
if (session.isActive())
|
||||
return;
|
||||
if (session.getDeployment() == null) session.setDeployment(deploymentContext.resolveDeployment(facade));
|
||||
if (session.isActive()) return;
|
||||
|
||||
// FYI: A refresh requires same scope, so same roles will be set.
|
||||
// Otherwise, refresh will fail and token will
|
||||
// FYI: A refresh requires same scope, so same roles will be set. Otherwise, refresh will fail and token will
|
||||
// not be updated
|
||||
session.refreshExpiredToken();
|
||||
if (session.isActive())
|
||||
return;
|
||||
if (session.isActive()) return;
|
||||
|
||||
request.getSessionInternal().removeNote(KeycloakSecurityContext.class.getName());
|
||||
request.setUserPrincipal(null);
|
||||
|
|
Loading…
Reference in a new issue