fix(ui): Long overdue - Fix red error screens during OIDC login, logout exception scenarios (#5708)

This commit is contained in:
John Joyce 2022-08-23 09:54:34 -07:00 committed by GitHub
parent fcdb8a2226
commit 5974721697
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 5 deletions

View File

@ -275,8 +275,17 @@ public class AuthenticationController extends Controller {
_logger.debug("Found previous login attempt. Removing it manually to prevent unexpected errors.");
_playSessionStore.set(playWebContext, client.getName() + ATTEMPTED_AUTHENTICATION_SUFFIX, "");
}
final HttpAction action = client.redirect(playWebContext);
return new PlayHttpActionAdapter().adapt(action.getCode(), playWebContext);
try {
final HttpAction action = client.redirect(playWebContext);
return new PlayHttpActionAdapter().adapt(action.getCode(), playWebContext);
} catch (Exception e) {
_logger.error("Caught exception while attempting to redirect to SSO identity provider! It's likely that SSO integration is mis-configured", e);
return redirect(
String.format("/login?error_msg=%s",
URLEncoder.encode("Failed to redirect to Single Sign-On provider. Please contact your DataHub Administrator, "
+ "or refer to server logs for more information.")));
}
}
private String encodeRedirectUri(final String redirectUri) {

View File

@ -1,6 +1,8 @@
package controllers;
import com.typesafe.config.Config;
import java.net.URLEncoder;
import lombok.extern.slf4j.Slf4j;
import org.pac4j.play.LogoutController;
import play.mvc.Result;
@ -10,6 +12,7 @@ import java.util.concurrent.ExecutionException;
/**
* Responsible for handling logout logic with oidc providers
*/
@Slf4j
public class CentralLogoutController extends LogoutController {
private static final String AUTH_BASE_URL_CONFIG_PATH = "auth.baseUrl";
@ -37,7 +40,15 @@ public class CentralLogoutController extends LogoutController {
*/
public Result executeLogout() throws ExecutionException, InterruptedException {
if (_isOidcEnabled) {
return logout().toCompletableFuture().get();
try {
return logout().toCompletableFuture().get();
} catch (Exception e) {
log.error("Caught exception while attempting to perform SSO logout! It's likely that SSO integration is mis-configured.", e);
return redirect(
String.format("/login?error_msg=%s",
URLEncoder.encode("Failed to sign out using Single Sign-On provider. Please contact your DataHub Administrator, "
+ "or refer to server logs for more information.")));
}
}
return redirect("/");
}

View File

@ -3,6 +3,7 @@ package controllers;
import client.AuthServiceClient;
import com.datahub.authentication.Authentication;
import com.linkedin.entity.client.EntityClient;
import java.net.URLEncoder;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import javax.annotation.Nonnull;
@ -45,12 +46,22 @@ public class SsoCallbackController extends CallbackController {
public CompletionStage<Result> handleCallback(String protocol) {
if (shouldHandleCallback(protocol)) {
log.debug(String.format("Handling SSO callback. Protocol: %s", protocol));
return callback();
return callback().handle((res, e) -> {
if (e != null) {
log.error("Caught exception while attempting to handle SSO callback! It's likely that SSO integration is mis-configured.", e);
return redirect(
String.format("/login?error_msg=%s",
URLEncoder.encode("Failed to sign in using Single Sign-On provider. Please contact your DataHub Administrator, "
+ "or refer to server logs for more information.")));
}
return res;
});
}
return CompletableFuture.completedFuture(internalServerError(
String.format("Failed to perform SSO callback. SSO is not enabled for protocol: %s", protocol)));
}
/**
* Logic responsible for delegating to protocol-specific callback logic.
*/

View File

@ -43,6 +43,8 @@ export type LogInProps = Record<string, never>;
export const LogIn: React.VFC<LogInProps> = () => {
const isLoggedIn = useReactiveVar(isLoggedInVar);
const location = useLocation();
const params = QueryString.parse(location.search);
const maybeRedirectError = params.error_msg;
const themeConfig = useTheme();
const [loading, setLoading] = useState(false);
@ -78,13 +80,15 @@ export const LogIn: React.VFC<LogInProps> = () => {
);
if (isLoggedIn) {
const params = QueryString.parse(location.search);
const maybeRedirectUri = params.redirect_uri;
return <Redirect to={(maybeRedirectUri && decodeURIComponent(maybeRedirectUri as string)) || '/'} />;
}
return (
<div className={styles.login_page}>
{maybeRedirectError && maybeRedirectError.length > 0 && (
<Message type="error" content={maybeRedirectError} />
)}
<div className={styles.login_box}>
<div className={styles.login_logo_box}>
<Image wrapperClassName={styles.logo_image} src={themeConfig.assets?.logoUrl} preview={false} />