Add Redirect Uri Handling for Confidential Flow (#17913)

* Add Redirect Uri Handling for Confidential Flow

* add redirect uri in login

* fix session redirect uri

* update redirect path to absolute path

---------

Co-authored-by: karanh37 <karanh37@gmail.com>
Co-authored-by: Karan Hotchandani <33024356+karanh37@users.noreply.github.com>
This commit is contained in:
Mohit Yadav 2024-09-20 10:31:54 +05:30 committed by GitHub
parent 5fc17e1d9f
commit 043b18ee0f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 23 additions and 7 deletions

View File

@ -119,6 +119,8 @@ public class AuthenticationCodeFlowHandler {
public static final String DEFAULT_PRINCIPAL_DOMAIN = "openmetadata.org";
public static final String OIDC_CREDENTIAL_PROFILE = "oidcCredentialProfile";
public static final String SESSION_REDIRECT_URI = "sessionRedirectUri";
public static final String REDIRECT_URI_KEY = "redirectUri";
private final OidcClient client;
private final List<String> claimsOrder;
private final Map<String, String> claimsMapping;
@ -247,11 +249,12 @@ public class AuthenticationCodeFlowHandler {
// Login
public void handleLogin(HttpServletRequest req, HttpServletResponse resp) {
try {
checkAndStoreRedirectUriInSession(req);
LOG.debug("Performing Auth Login For User Session: {} ", req.getSession().getId());
Optional<OidcCredentials> credentials = getUserCredentialsFromSession(req);
if (credentials.isPresent()) {
LOG.debug("Auth Tokens Located from Session: {} ", req.getSession().getId());
sendRedirectWithToken(resp, credentials.get());
sendRedirectWithToken(req, resp, credentials.get());
} else {
LOG.debug("Performing Auth Code Flow to Idp: {} ", req.getSession().getId());
Map<String, String> params = buildLoginParams();
@ -278,6 +281,15 @@ public class AuthenticationCodeFlowHandler {
}
}
private void checkAndStoreRedirectUriInSession(HttpServletRequest request) {
String redirectUri = request.getParameter(REDIRECT_URI_KEY);
if (nullOrEmpty(redirectUri)) {
throw new TechnicalException("Redirect URI is required");
}
request.getSession().setAttribute(SESSION_REDIRECT_URI, redirectUri);
}
// Callback
public void handleCallback(HttpServletRequest req, HttpServletResponse resp) {
try {
@ -322,7 +334,7 @@ public class AuthenticationCodeFlowHandler {
req.getSession().setAttribute(OIDC_CREDENTIAL_PROFILE, credentials);
// Redirect
sendRedirectWithToken(resp, credentials);
sendRedirectWithToken(req, resp, credentials);
} catch (Exception e) {
getErrorMessage(resp, e);
}
@ -371,7 +383,7 @@ public class AuthenticationCodeFlowHandler {
LOG.debug(
"Credentials Not Found For User Session: {}, Redirect to Logout ",
httpServletRequest.getSession().getId());
httpServletResponse.sendRedirect(String.format("%s/logout", serverUrl));
this.handleLogout(httpServletRequest, httpServletResponse);
}
} catch (Exception e) {
getErrorMessage(httpServletResponse, new TechnicalException(e));
@ -638,7 +650,8 @@ public class AuthenticationCodeFlowHandler {
"<p> [Auth Callback Servlet] Failed in Auth Login : %s </p>", e.getMessage()));
}
private void sendRedirectWithToken(HttpServletResponse response, OidcCredentials credentials)
private void sendRedirectWithToken(
HttpServletRequest request, HttpServletResponse response, OidcCredentials credentials)
throws ParseException, IOException {
JWT jwt = credentials.getIdToken();
Map<String, Object> claims = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
@ -647,10 +660,12 @@ public class AuthenticationCodeFlowHandler {
String userName = findUserNameFromClaims(claimsMapping, claimsOrder, claims);
String email = findEmailFromClaims(claimsMapping, claimsOrder, claims, principalDomain);
String redirectUri = (String) request.getSession().getAttribute(SESSION_REDIRECT_URI);
String url =
String.format(
"%s/auth/callback?id_token=%s&email=%s&name=%s",
serverUrl, credentials.getIdToken().getParsedString(), email, userName);
"%s?id_token=%s&email=%s&name=%s",
redirectUri, credentials.getIdToken().getParsedString(), email, userName);
response.sendRedirect(url);
}

View File

@ -34,7 +34,8 @@ export const GenericAuthenticator = forwardRef(
const handleLogin = () => {
setIsAuthenticated(false);
setIsSigningUp(true);
window.location.assign('api/v1/auth/login');
const redirectUri = `${window.location.origin}${ROUTES.AUTH_CALLBACK}`;
window.location.assign(`api/v1/auth/login?redirectUri=${redirectUri}`);
};
const handleLogout = async () => {