mirror of
https://github.com/datahub-project/datahub.git
synced 2025-10-25 16:05:11 +00:00
fix(authentication): fix PlayCacheSessionStore (#14754)
Co-authored-by: trialiya <trialiya@gmail.com> Co-authored-by: Deepak Garg <deepak.garg@datahub.com>
This commit is contained in:
parent
ef0b4a71ce
commit
b45d606062
@ -3,7 +3,6 @@ package auth.sso.oidc;
|
|||||||
import static auth.AuthUtils.*;
|
import static auth.AuthUtils.*;
|
||||||
import static com.linkedin.metadata.Constants.CORP_USER_ENTITY_NAME;
|
import static com.linkedin.metadata.Constants.CORP_USER_ENTITY_NAME;
|
||||||
import static com.linkedin.metadata.Constants.GROUP_MEMBERSHIP_ASPECT_NAME;
|
import static com.linkedin.metadata.Constants.GROUP_MEMBERSHIP_ASPECT_NAME;
|
||||||
import static org.pac4j.play.store.PlayCookieSessionStore.*;
|
|
||||||
import static play.mvc.Results.internalServerError;
|
import static play.mvc.Results.internalServerError;
|
||||||
import static utils.FrontendConstants.SSO_LOGIN;
|
import static utils.FrontendConstants.SSO_LOGIN;
|
||||||
|
|
||||||
@ -50,7 +49,6 @@ import java.net.URLEncoder;
|
|||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -71,6 +69,7 @@ import org.pac4j.core.context.CallContext;
|
|||||||
import org.pac4j.core.context.Cookie;
|
import org.pac4j.core.context.Cookie;
|
||||||
import org.pac4j.core.context.FrameworkParameters;
|
import org.pac4j.core.context.FrameworkParameters;
|
||||||
import org.pac4j.core.context.WebContext;
|
import org.pac4j.core.context.WebContext;
|
||||||
|
import org.pac4j.core.context.session.SessionStore;
|
||||||
import org.pac4j.core.credentials.Credentials;
|
import org.pac4j.core.credentials.Credentials;
|
||||||
import org.pac4j.core.engine.DefaultCallbackLogic;
|
import org.pac4j.core.engine.DefaultCallbackLogic;
|
||||||
import org.pac4j.core.exception.http.HttpAction;
|
import org.pac4j.core.exception.http.HttpAction;
|
||||||
@ -80,10 +79,10 @@ import org.pac4j.core.profile.ProfileManager;
|
|||||||
import org.pac4j.core.profile.UserProfile;
|
import org.pac4j.core.profile.UserProfile;
|
||||||
import org.pac4j.core.util.CommonHelper;
|
import org.pac4j.core.util.CommonHelper;
|
||||||
import org.pac4j.core.util.Pac4jConstants;
|
import org.pac4j.core.util.Pac4jConstants;
|
||||||
import org.pac4j.play.store.PlayCookieSessionStore;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import play.mvc.Result;
|
import play.mvc.Result;
|
||||||
|
import utils.SerializationUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class contains the logic that is executed when an OpenID Connect Identity Provider redirects
|
* This class contains the logic that is executed when an OpenID Connect Identity Provider redirects
|
||||||
@ -207,21 +206,15 @@ public class OidcCallbackLogic extends DefaultCallbackLogic {
|
|||||||
|
|
||||||
private void setContextRedirectUrl(CallContext ctx) {
|
private void setContextRedirectUrl(CallContext ctx) {
|
||||||
WebContext context = ctx.webContext();
|
WebContext context = ctx.webContext();
|
||||||
PlayCookieSessionStore sessionStore = (PlayCookieSessionStore) ctx.sessionStore();
|
SessionStore sessionStore = ctx.sessionStore();
|
||||||
|
|
||||||
Optional<Cookie> redirectUrl =
|
context.getRequestCookies().stream()
|
||||||
context.getRequestCookies().stream()
|
.filter(cookie -> REDIRECT_URL_COOKIE_NAME.equals(cookie.getName()))
|
||||||
.filter(cookie -> REDIRECT_URL_COOKIE_NAME.equals(cookie.getName()))
|
.map(Cookie::getValue)
|
||||||
.findFirst();
|
.map(SerializationUtils::deserializeFoundAction)
|
||||||
redirectUrl.ifPresent(
|
.findFirst()
|
||||||
cookie ->
|
.ifPresent(
|
||||||
sessionStore.set(
|
foundAction -> sessionStore.set(context, Pac4jConstants.REQUESTED_URL, foundAction));
|
||||||
context,
|
|
||||||
Pac4jConstants.REQUESTED_URL,
|
|
||||||
sessionStore
|
|
||||||
.getSerializer()
|
|
||||||
.deserializeFromBytes(
|
|
||||||
uncompressBytes(Base64.getDecoder().decode(cookie.getValue())))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result handleOidcCallback(
|
private Result handleOidcCallback(
|
||||||
|
|||||||
@ -2,7 +2,6 @@ package controllers;
|
|||||||
|
|
||||||
import static auth.AuthUtils.*;
|
import static auth.AuthUtils.*;
|
||||||
import static org.pac4j.core.client.IndirectClient.ATTEMPTED_AUTHENTICATION_SUFFIX;
|
import static org.pac4j.core.client.IndirectClient.ATTEMPTED_AUTHENTICATION_SUFFIX;
|
||||||
import static org.pac4j.play.store.PlayCookieSessionStore.*;
|
|
||||||
import static utils.FrontendConstants.FALLBACK_LOGIN;
|
import static utils.FrontendConstants.FALLBACK_LOGIN;
|
||||||
import static utils.FrontendConstants.GUEST_LOGIN;
|
import static utils.FrontendConstants.GUEST_LOGIN;
|
||||||
import static utils.FrontendConstants.PASSWORD_LOGIN;
|
import static utils.FrontendConstants.PASSWORD_LOGIN;
|
||||||
@ -28,7 +27,6 @@ import java.net.URISyntaxException;
|
|||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@ -37,11 +35,11 @@ import org.apache.http.client.RedirectException;
|
|||||||
import org.pac4j.core.client.Client;
|
import org.pac4j.core.client.Client;
|
||||||
import org.pac4j.core.context.CallContext;
|
import org.pac4j.core.context.CallContext;
|
||||||
import org.pac4j.core.context.WebContext;
|
import org.pac4j.core.context.WebContext;
|
||||||
|
import org.pac4j.core.context.session.SessionStore;
|
||||||
import org.pac4j.core.exception.http.FoundAction;
|
import org.pac4j.core.exception.http.FoundAction;
|
||||||
import org.pac4j.core.exception.http.RedirectionAction;
|
import org.pac4j.core.exception.http.RedirectionAction;
|
||||||
import org.pac4j.play.PlayWebContext;
|
import org.pac4j.play.PlayWebContext;
|
||||||
import org.pac4j.play.http.PlayHttpActionAdapter;
|
import org.pac4j.play.http.PlayHttpActionAdapter;
|
||||||
import org.pac4j.play.store.PlayCookieSessionStore;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import play.data.validation.Constraints;
|
import play.data.validation.Constraints;
|
||||||
@ -51,6 +49,7 @@ import play.mvc.Http;
|
|||||||
import play.mvc.Result;
|
import play.mvc.Result;
|
||||||
import play.mvc.Results;
|
import play.mvc.Results;
|
||||||
import security.AuthenticationManager;
|
import security.AuthenticationManager;
|
||||||
|
import utils.SerializationUtils;
|
||||||
|
|
||||||
public class AuthenticationController extends Controller {
|
public class AuthenticationController extends Controller {
|
||||||
public static final String AUTH_VERBOSE_LOGGING = "auth.verbose.logging";
|
public static final String AUTH_VERBOSE_LOGGING = "auth.verbose.logging";
|
||||||
@ -75,7 +74,7 @@ public class AuthenticationController extends Controller {
|
|||||||
|
|
||||||
@Inject private org.pac4j.core.config.Config ssoConfig;
|
@Inject private org.pac4j.core.config.Config ssoConfig;
|
||||||
|
|
||||||
@VisibleForTesting @Inject protected PlayCookieSessionStore playCookieSessionStore;
|
@VisibleForTesting @Inject protected SessionStore sessionStore;
|
||||||
|
|
||||||
@VisibleForTesting @Inject protected SsoManager ssoManager;
|
@VisibleForTesting @Inject protected SsoManager ssoManager;
|
||||||
|
|
||||||
@ -371,11 +370,9 @@ public class AuthenticationController extends Controller {
|
|||||||
// to reduce size of the session cookie
|
// to reduce size of the session cookie
|
||||||
FoundAction foundAction =
|
FoundAction foundAction =
|
||||||
new FoundAction(BasePathUtils.addBasePath(redirectPath, this.basePath));
|
new FoundAction(BasePathUtils.addBasePath(redirectPath, this.basePath));
|
||||||
byte[] javaSerBytes =
|
|
||||||
((PlayCookieSessionStore) ctx.sessionStore()).getSerializer().serializeToBytes(foundAction);
|
|
||||||
String serialized = Base64.getEncoder().encodeToString(compressBytes(javaSerBytes));
|
|
||||||
Http.CookieBuilder redirectCookieBuilder =
|
Http.CookieBuilder redirectCookieBuilder =
|
||||||
Http.Cookie.builder(REDIRECT_URL_COOKIE_NAME, serialized);
|
Http.Cookie.builder(
|
||||||
|
REDIRECT_URL_COOKIE_NAME, SerializationUtils.serializeFoundAction(foundAction));
|
||||||
redirectCookieBuilder.withPath(BasePathUtils.addBasePath("/", this.basePath));
|
redirectCookieBuilder.withPath(BasePathUtils.addBasePath("/", this.basePath));
|
||||||
redirectCookieBuilder.withSecure(true);
|
redirectCookieBuilder.withSecure(true);
|
||||||
redirectCookieBuilder.withHttpOnly(true);
|
redirectCookieBuilder.withHttpOnly(true);
|
||||||
@ -422,7 +419,7 @@ public class AuthenticationController extends Controller {
|
|||||||
PlayWebContext webContext = new PlayWebContext(request);
|
PlayWebContext webContext = new PlayWebContext(request);
|
||||||
|
|
||||||
// Then create CallContext using the web context and session store
|
// Then create CallContext using the web context and session store
|
||||||
return new CallContext(webContext, playCookieSessionStore);
|
return new CallContext(webContext, sessionStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configurePac4jSessionStore(CallContext ctx, Client client) {
|
private void configurePac4jSessionStore(CallContext ctx, Client client) {
|
||||||
@ -431,11 +428,11 @@ public class AuthenticationController extends Controller {
|
|||||||
// This is to prevent previous login attempts from being cached.
|
// This is to prevent previous login attempts from being cached.
|
||||||
// We replicate the logic here, which is buried in the Pac4j client.
|
// We replicate the logic here, which is buried in the Pac4j client.
|
||||||
Optional<Object> attempt =
|
Optional<Object> attempt =
|
||||||
playCookieSessionStore.get(context, client.getName() + ATTEMPTED_AUTHENTICATION_SUFFIX);
|
ctx.sessionStore().get(context, client.getName() + ATTEMPTED_AUTHENTICATION_SUFFIX);
|
||||||
if (attempt.isPresent() && !"".equals(attempt.get())) {
|
if (attempt.isPresent() && !"".equals(attempt.get())) {
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Found previous login attempt. Removing it manually to prevent unexpected errors.");
|
"Found previous login attempt. Removing it manually to prevent unexpected errors.");
|
||||||
playCookieSessionStore.set(context, client.getName() + ATTEMPTED_AUTHENTICATION_SUFFIX, "");
|
ctx.sessionStore().set(context, client.getName() + ATTEMPTED_AUTHENTICATION_SUFFIX, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
27
datahub-frontend/app/utils/SerializationUtils.java
Normal file
27
datahub-frontend/app/utils/SerializationUtils.java
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package utils;
|
||||||
|
|
||||||
|
import static org.pac4j.play.store.PlayCookieSessionStore.compressBytes;
|
||||||
|
import static org.pac4j.play.store.PlayCookieSessionStore.uncompressBytes;
|
||||||
|
|
||||||
|
import java.util.Base64;
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import org.pac4j.core.exception.http.FoundAction;
|
||||||
|
import org.pac4j.core.util.serializer.JavaSerializer;
|
||||||
|
|
||||||
|
public class SerializationUtils {
|
||||||
|
|
||||||
|
private static final JavaSerializer JAVA_SERIALIZER = new JavaSerializer();
|
||||||
|
|
||||||
|
private SerializationUtils() {}
|
||||||
|
|
||||||
|
public static String serializeFoundAction(@Nonnull final FoundAction foundAction) {
|
||||||
|
byte[] javaSerBytes = JAVA_SERIALIZER.serializeToBytes(foundAction);
|
||||||
|
return Base64.getEncoder().encodeToString(compressBytes(javaSerBytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FoundAction deserializeFoundAction(@Nonnull final String serialized) {
|
||||||
|
return (FoundAction)
|
||||||
|
JAVA_SERIALIZER.deserializeFromBytes(
|
||||||
|
uncompressBytes(Base64.getDecoder().decode(serialized)));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -100,7 +100,7 @@ public class AuthenticationControllerTest {
|
|||||||
|
|
||||||
// Create the controller
|
// Create the controller
|
||||||
controller = new AuthenticationController(mockConfig);
|
controller = new AuthenticationController(mockConfig);
|
||||||
controller.playCookieSessionStore = playCookieSessionStore;
|
controller.sessionStore = playCookieSessionStore;
|
||||||
controller.ssoManager = ssoManager;
|
controller.ssoManager = ssoManager;
|
||||||
controller.authClient = authClient;
|
controller.authClient = authClient;
|
||||||
}
|
}
|
||||||
@ -353,7 +353,7 @@ public class AuthenticationControllerTest {
|
|||||||
AuthenticationController testController = new AuthenticationController(config);
|
AuthenticationController testController = new AuthenticationController(config);
|
||||||
testController.ssoManager = ssoManager;
|
testController.ssoManager = ssoManager;
|
||||||
testController.authClient = authClient;
|
testController.authClient = authClient;
|
||||||
testController.playCookieSessionStore = playCookieSessionStore;
|
testController.sessionStore = playCookieSessionStore;
|
||||||
|
|
||||||
// Configure SSO to be enabled
|
// Configure SSO to be enabled
|
||||||
when(ssoManager.isSsoEnabled()).thenReturn(true);
|
when(ssoManager.isSsoEnabled()).thenReturn(true);
|
||||||
@ -408,7 +408,7 @@ public class AuthenticationControllerTest {
|
|||||||
AuthenticationController testController = new AuthenticationController(config);
|
AuthenticationController testController = new AuthenticationController(config);
|
||||||
testController.ssoManager = ssoManager;
|
testController.ssoManager = ssoManager;
|
||||||
testController.authClient = authClient;
|
testController.authClient = authClient;
|
||||||
testController.playCookieSessionStore = playCookieSessionStore;
|
testController.sessionStore = playCookieSessionStore;
|
||||||
|
|
||||||
// Configure SSO to be enabled
|
// Configure SSO to be enabled
|
||||||
when(ssoManager.isSsoEnabled()).thenReturn(true);
|
when(ssoManager.isSsoEnabled()).thenReturn(true);
|
||||||
@ -465,7 +465,7 @@ public class AuthenticationControllerTest {
|
|||||||
Config config = ConfigFactory.parseMap(configMap);
|
Config config = ConfigFactory.parseMap(configMap);
|
||||||
AuthenticationController testController = new AuthenticationController(config);
|
AuthenticationController testController = new AuthenticationController(config);
|
||||||
testController.ssoManager = ssoManager;
|
testController.ssoManager = ssoManager;
|
||||||
testController.playCookieSessionStore = playCookieSessionStore;
|
testController.sessionStore = playCookieSessionStore;
|
||||||
|
|
||||||
// Configure SSO to be enabled
|
// Configure SSO to be enabled
|
||||||
when(ssoManager.isSsoEnabled()).thenReturn(true);
|
when(ssoManager.isSsoEnabled()).thenReturn(true);
|
||||||
@ -619,7 +619,7 @@ public class AuthenticationControllerTest {
|
|||||||
Config config = ConfigFactory.parseMap(configMap);
|
Config config = ConfigFactory.parseMap(configMap);
|
||||||
AuthenticationController testController = new AuthenticationController(config);
|
AuthenticationController testController = new AuthenticationController(config);
|
||||||
testController.ssoManager = ssoManager;
|
testController.ssoManager = ssoManager;
|
||||||
testController.playCookieSessionStore = playCookieSessionStore;
|
testController.sessionStore = playCookieSessionStore;
|
||||||
|
|
||||||
// Configure SSO to be enabled
|
// Configure SSO to be enabled
|
||||||
when(ssoManager.isSsoEnabled()).thenReturn(true);
|
when(ssoManager.isSsoEnabled()).thenReturn(true);
|
||||||
|
|||||||
@ -49,8 +49,6 @@ export JAVA_OPTS="${JAVA_MEMORY_OPTS:-"-Xms512m -Xmx1024m"} \
|
|||||||
-Djava.security.auth.login.config=datahub-frontend/conf/jaas.conf \
|
-Djava.security.auth.login.config=datahub-frontend/conf/jaas.conf \
|
||||||
-Dlogback.configurationFile=datahub-frontend/conf/logback.xml \
|
-Dlogback.configurationFile=datahub-frontend/conf/logback.xml \
|
||||||
-Dlogback.debug=false \
|
-Dlogback.debug=false \
|
||||||
--add-opens java.base/java.lang=ALL-UNNAMED \
|
|
||||||
--add-opens=java.base/java.util=ALL-UNNAMED \
|
|
||||||
${PROMETHEUS_AGENT:-} ${OTEL_AGENT:-} \
|
${PROMETHEUS_AGENT:-} ${OTEL_AGENT:-} \
|
||||||
${TRUSTSTORE_FILE:-} ${TRUSTSTORE_TYPE:-} ${TRUSTSTORE_PASSWORD:-} \
|
${TRUSTSTORE_FILE:-} ${TRUSTSTORE_TYPE:-} ${TRUSTSTORE_PASSWORD:-} \
|
||||||
${HTTP_PROXY:-} ${HTTPS_PROXY:-} ${NO_PROXY:-} \
|
${HTTP_PROXY:-} ${HTTPS_PROXY:-} ${NO_PROXY:-} \
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user