mirror of
https://github.com/datahub-project/datahub.git
synced 2025-12-29 19:07:33 +00:00
feat(auth) Update auth cookies to have same-site none for chrome extension (#6976)
This commit is contained in:
parent
dcf389d35f
commit
0337110928
@ -4,6 +4,7 @@ import com.linkedin.common.urn.CorpuserUrn;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import play.mvc.Http;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.HashMap;
|
||||
@ -44,6 +45,11 @@ public class AuthUtils {
|
||||
public static final Integer DEFAULT_SESSION_TTL_HOURS = 720;
|
||||
public static final CorpuserUrn DEFAULT_ACTOR_URN = new CorpuserUrn("datahub");
|
||||
|
||||
public static final String AUTH_COOKIE_SAME_SITE = "play.http.session.sameSite";
|
||||
public static final String DEFAULT_AUTH_COOKIE_SAME_SITE = "LAX";
|
||||
public static final String AUTH_COOKIE_SECURE = "play.http.session.secure";
|
||||
public static final boolean DEFAULT_AUTH_COOKIE_SECURE = false;
|
||||
|
||||
public static final String LOGIN_ROUTE = "/login";
|
||||
public static final String USER_NAME = "username";
|
||||
public static final String PASSWORD = "password";
|
||||
@ -96,11 +102,18 @@ public class AuthUtils {
|
||||
* @param actorUrn the urn of the authenticated actor, e.g. "urn:li:corpuser:datahub"
|
||||
* @param ttlInHours the number of hours until the actor cookie expires after being set
|
||||
*/
|
||||
public static Http.Cookie createActorCookie(final String actorUrn, final Integer ttlInHours) {
|
||||
public static Http.Cookie createActorCookie(
|
||||
@Nonnull final String actorUrn,
|
||||
@Nonnull final Integer ttlInHours,
|
||||
@Nonnull final String sameSite,
|
||||
final boolean isSecure
|
||||
) {
|
||||
return Http.Cookie.builder(ACTOR, actorUrn)
|
||||
.withHttpOnly(false)
|
||||
.withMaxAge(Duration.of(ttlInHours, ChronoUnit.HOURS))
|
||||
.build();
|
||||
.withHttpOnly(false)
|
||||
.withMaxAge(Duration.of(ttlInHours, ChronoUnit.HOURS))
|
||||
.withSameSite(convertSameSiteValue(sameSite))
|
||||
.withSecure(isSecure)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Map<String, String> createSessionMap(final String userUrnStr, final String accessToken) {
|
||||
@ -112,4 +125,13 @@ public class AuthUtils {
|
||||
|
||||
private AuthUtils() { }
|
||||
|
||||
private static Http.Cookie.SameSite convertSameSiteValue(@Nonnull final String sameSiteValue) {
|
||||
try {
|
||||
return Http.Cookie.SameSite.valueOf(sameSiteValue);
|
||||
} catch (IllegalArgumentException e) {
|
||||
log.warn(String.format("Invalid AUTH_COOKIE_SAME_SITE value: %s. Using LAX instead.", sameSiteValue), e);
|
||||
return Http.Cookie.SameSite.LAX;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -28,6 +28,8 @@ public class SsoConfigs {
|
||||
private final String _authSuccessRedirectPath;
|
||||
private final Integer _sessionTtlInHours;
|
||||
private final Boolean _oidcEnabled;
|
||||
private final String _authCookieSameSite;
|
||||
private final Boolean _authCookieSecure;
|
||||
|
||||
public SsoConfigs(final com.typesafe.config.Config configs) {
|
||||
_authBaseUrl = getRequired(configs, AUTH_BASE_URL_CONFIG_PATH);
|
||||
@ -46,6 +48,14 @@ public class SsoConfigs {
|
||||
_oidcEnabled = configs.hasPath(OIDC_ENABLED_CONFIG_PATH)
|
||||
&& Boolean.TRUE.equals(
|
||||
Boolean.parseBoolean(configs.getString(OIDC_ENABLED_CONFIG_PATH)));
|
||||
_authCookieSameSite = getOptional(
|
||||
configs,
|
||||
AUTH_COOKIE_SAME_SITE,
|
||||
DEFAULT_AUTH_COOKIE_SAME_SITE);
|
||||
_authCookieSecure = Boolean.parseBoolean(getOptional(
|
||||
configs,
|
||||
AUTH_COOKIE_SECURE,
|
||||
String.valueOf(DEFAULT_AUTH_COOKIE_SECURE)));
|
||||
}
|
||||
|
||||
public String getAuthBaseUrl() {
|
||||
@ -64,6 +74,14 @@ public class SsoConfigs {
|
||||
return _sessionTtlInHours;
|
||||
}
|
||||
|
||||
public String getAuthCookieSameSite() {
|
||||
return _authCookieSameSite;
|
||||
}
|
||||
|
||||
public boolean getAuthCookieSecure() {
|
||||
return _authCookieSecure;
|
||||
}
|
||||
|
||||
public Boolean isOidcEnabled() {
|
||||
return _oidcEnabled;
|
||||
}
|
||||
|
||||
@ -154,7 +154,14 @@ public class OidcCallbackLogic extends DefaultCallbackLogic<Result, PlayWebConte
|
||||
final String accessToken = _authClient.generateSessionTokenForUser(corpUserUrn.getId());
|
||||
return result
|
||||
.withSession(createSessionMap(corpUserUrn.toString(), accessToken))
|
||||
.withCookies(createActorCookie(corpUserUrn.toString(), oidcConfigs.getSessionTtlInHours()));
|
||||
.withCookies(
|
||||
createActorCookie(
|
||||
corpUserUrn.toString(),
|
||||
oidcConfigs.getSessionTtlInHours(),
|
||||
oidcConfigs.getAuthCookieSameSite(),
|
||||
oidcConfigs.getAuthCookieSecure()
|
||||
)
|
||||
);
|
||||
}
|
||||
return internalServerError(
|
||||
"Failed to authenticate current user. Cannot find valid identity provider profile in session.");
|
||||
|
||||
@ -32,7 +32,11 @@ import play.mvc.Result;
|
||||
import play.mvc.Results;
|
||||
import security.AuthenticationManager;
|
||||
|
||||
import static auth.AuthUtils.AUTH_COOKIE_SAME_SITE;
|
||||
import static auth.AuthUtils.AUTH_COOKIE_SECURE;
|
||||
import static auth.AuthUtils.DEFAULT_ACTOR_URN;
|
||||
import static auth.AuthUtils.DEFAULT_AUTH_COOKIE_SAME_SITE;
|
||||
import static auth.AuthUtils.DEFAULT_AUTH_COOKIE_SECURE;
|
||||
import static auth.AuthUtils.DEFAULT_SESSION_TTL_HOURS;
|
||||
import static auth.AuthUtils.EMAIL;
|
||||
import static auth.AuthUtils.FULL_NAME;
|
||||
@ -115,10 +119,15 @@ public class AuthenticationController extends Controller {
|
||||
// 3. If no auth enabled, fallback to using default user account & redirect.
|
||||
// Generate GMS session token, TODO:
|
||||
final String accessToken = _authClient.generateSessionTokenForUser(DEFAULT_ACTOR_URN.getId());
|
||||
int ttlInHours = _configs.hasPath(SESSION_TTL_CONFIG_PATH) ? _configs.getInt(SESSION_TTL_CONFIG_PATH)
|
||||
: DEFAULT_SESSION_TTL_HOURS;
|
||||
String authCookieSameSite = _configs.hasPath(AUTH_COOKIE_SAME_SITE) ? _configs.getString(AUTH_COOKIE_SAME_SITE)
|
||||
: DEFAULT_AUTH_COOKIE_SAME_SITE;
|
||||
boolean authCookieSecure = _configs.hasPath(AUTH_COOKIE_SECURE) ? _configs.getBoolean(AUTH_COOKIE_SECURE)
|
||||
: DEFAULT_AUTH_COOKIE_SECURE;
|
||||
|
||||
return Results.redirect(redirectPath).withSession(createSessionMap(DEFAULT_ACTOR_URN.toString(), accessToken))
|
||||
.withCookies(createActorCookie(DEFAULT_ACTOR_URN.toString(),
|
||||
_configs.hasPath(SESSION_TTL_CONFIG_PATH) ? _configs.getInt(SESSION_TTL_CONFIG_PATH)
|
||||
: DEFAULT_SESSION_TTL_HOURS));
|
||||
.withCookies(createActorCookie(DEFAULT_ACTOR_URN.toString(), ttlInHours, authCookieSameSite, authCookieSecure));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -329,7 +338,12 @@ public class AuthenticationController extends Controller {
|
||||
private Result createSession(String userUrnString, String accessToken) {
|
||||
int ttlInHours = _configs.hasPath(SESSION_TTL_CONFIG_PATH) ? _configs.getInt(SESSION_TTL_CONFIG_PATH)
|
||||
: DEFAULT_SESSION_TTL_HOURS;
|
||||
String authCookieSameSite = _configs.hasPath(AUTH_COOKIE_SAME_SITE) ? _configs.getString(AUTH_COOKIE_SAME_SITE)
|
||||
: DEFAULT_AUTH_COOKIE_SAME_SITE;
|
||||
boolean authCookieSecure = _configs.hasPath(AUTH_COOKIE_SECURE) ? _configs.getBoolean(AUTH_COOKIE_SECURE)
|
||||
: DEFAULT_AUTH_COOKIE_SECURE;
|
||||
|
||||
return Results.ok().withSession(createSessionMap(userUrnString, accessToken))
|
||||
.withCookies(createActorCookie(userUrnString, ttlInHours));
|
||||
.withCookies(createActorCookie(userUrnString, ttlInHours, authCookieSameSite, authCookieSecure));
|
||||
}
|
||||
}
|
||||
@ -36,6 +36,15 @@ play.http.server.akka.max-header-count = ${?DATAHUB_AKKA_MAX_HEADER_COUNT}
|
||||
play.server.akka.max-header-size = 8k
|
||||
play.server.akka.max-header-size = ${?DATAHUB_AKKA_MAX_HEADER_VALUE_LENGTH}
|
||||
|
||||
# Update AUTH_COOKIE_SAME_SITE and AUTH_COOKIE_SECURE in order to change how authentication cookies
|
||||
# are configured. If you wish cookies to be sent in first and third party contexts, set
|
||||
# AUTH_COOKIE_SAME_SITE = "NONE" and AUTH_COOKIE_SECURE = true. If AUTH_COOKIE_SAME_SITE is "NONE",
|
||||
# AUTH_COOKIE_SECURE must be set to true.
|
||||
play.http.session.sameSite = "LAX"
|
||||
play.http.session.sameSite = ${?AUTH_COOKIE_SAME_SITE}
|
||||
play.http.session.secure = false
|
||||
play.http.session.secure = ${?AUTH_COOKIE_SECURE}
|
||||
|
||||
play.filters {
|
||||
enabled = [
|
||||
play.filters.gzip.GzipFilter
|
||||
|
||||
@ -60,6 +60,7 @@ dependencies {
|
||||
implementation externalDependency.kafkaClients
|
||||
implementation externalDependency.awsMskIamAuth
|
||||
|
||||
testImplementation 'org.seleniumhq.selenium:htmlunit-driver:2.67.0'
|
||||
testImplementation externalDependency.mockito
|
||||
testImplementation externalDependency.playTest
|
||||
testImplementation 'org.awaitility:awaitility:4.2.0'
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user