diff --git a/src/main/java/com/okta/tools/saml/OktaSaml.java b/src/main/java/com/okta/tools/saml/OktaSaml.java index 041e079..51bc285 100644 --- a/src/main/java/com/okta/tools/saml/OktaSaml.java +++ b/src/main/java/com/okta/tools/saml/OktaSaml.java @@ -50,22 +50,46 @@ public String getSamlResponse() throws IOException { private String getSamlResponseForAws(String oktaSessionToken) throws IOException { Document document = launchOktaAwsAppWithSessionToken(environment.oktaAwsAppUrl, oktaSessionToken); - Elements samlResponseInputElement = document.select("form input[name=SAMLResponse]"); - if (samlResponseInputElement.isEmpty()) { - throw new RuntimeException("You do not have access to AWS through Okta. \nPlease contact your administrator."); - } - return samlResponseInputElement.attr("value"); + return getSamlResponseForAwsFromDocument(document); } private String getSamlResponseForAwsRefresh() throws IOException { Document document = launchOktaAwsApp(environment.oktaAwsAppUrl); + return getSamlResponseForAwsFromDocument(document); + } + + private String getSamlResponseForAwsFromDocument(Document document) { Elements samlResponseInputElement = document.select("form input[name=SAMLResponse]"); if (samlResponseInputElement.isEmpty()) { - throw new RuntimeException("You do not have access to AWS through Okta. \nPlease contact your administrator."); + if (isPasswordAuthenticationChallenge(document)) { + throw new IllegalStateException("Unsupported App sign on rule: 'Prompt for re-authentication'. \nPlease contact your administrator."); + } else if (isPromptForFactorChallenge(document)) { + throw new IllegalStateException("Unsupported App sign on rule: 'Prompt for factor'. \nPlease contact your administrator."); + } else { + Elements errorContent = document.getElementsByClass("error-content"); + Elements errorHeadline = errorContent.select("h1"); + if (errorHeadline.hasText()) { + throw new RuntimeException(errorHeadline.text()); + } else { + throw new RuntimeException("You do not have access to AWS through Okta. \nPlease contact your administrator."); + } + } } return samlResponseInputElement.attr("value"); } + // Heuristic based on undocumented behavior observed experimentally + // This condition may be missed if Okta significantly changes the app-level re-auth page + private boolean isPasswordAuthenticationChallenge(Document document) { + return document.getElementById("password-verification-challenge") != null; + } + + // Heuristic based on undocumented behavior observed experimentally + // This condition may be missed if Okta significantly changes the app-level MFA page + private boolean isPromptForFactorChallenge(Document document) { + return document.getElementById("okta-sign-in") != null; + } + private Document launchOktaAwsAppWithSessionToken(String appUrl, String oktaSessionToken) throws IOException { return launchOktaAwsApp(appUrl + "?onetimetoken=" + oktaSessionToken); }