Search in sources :

Example 1 with XUIState

use of org.forgerock.openam.xui.XUIState in project OpenAM by OpenRock.

the class SAML2Proxy method processSamlResponse.

/**
     * Processes the SAML response for the SAML2 authentication module and then directs the user back to the
     * authentication process differently for XUI and non-XUI cases.
     *
     * @param request The HTTP request.
     * @param response The HTTP response.
     * @param out The {@link PrintWriter}.
     * @throws IOException If there was an IO error while retrieving the SAML response.
     */
public static void processSamlResponse(HttpServletRequest request, HttpServletResponse response, PrintWriter out) throws IOException {
    String url = getUrl(request, response);
    XUIState xuiState = InjectorHolder.getInstance(XUIState.class);
    if (xuiState.isXUIEnabled()) {
        response.sendRedirect(url);
    } else {
        out.println(getAutoSubmittingFormHtml(url));
    }
}
Also used : XUIState(org.forgerock.openam.xui.XUIState)

Example 2 with XUIState

use of org.forgerock.openam.xui.XUIState in project OpenAM by OpenRock.

the class SAML2 method setCookiesForRedirects.

/**
     * "Inspired" by the OAuth2 module. We use this cookie to remind us exactly where we are when
     * returning from a remote server as we currently cannot trust the RedirectCallback's authentication
     * framework equiv.
     */
private void setCookiesForRedirects(final HttpServletRequest request, final HttpServletResponse response) {
    final Set<String> domains = AuthClientUtils.getCookieDomainsForRequest(request);
    final StringBuilder originalUrl = new StringBuilder();
    final String requestedQuery = request.getQueryString();
    final XUIState xuiState = InjectorHolder.getInstance(XUIState.class);
    if (xuiState.isXUIEnabled()) {
        originalUrl.append(request.getContextPath());
    } else {
        originalUrl.append(request.getRequestURI());
    }
    if (StringUtils.isNotEmpty(realm)) {
        originalUrl.append("?realm=").append(URLEncDec.encode(realm));
    }
    if (requestedQuery != null) {
        originalUrl.append(originalUrl.indexOf("?") == -1 ? '?' : '&');
        originalUrl.append(requestedQuery);
    }
    // Set the return URL Cookie
    for (String domain : domains) {
        CookieUtils.addCookieToResponse(response, CookieUtils.newCookie(Constants.AM_LOCATION_COOKIE, originalUrl.toString(), "/", domain));
    }
}
Also used : XUIState(org.forgerock.openam.xui.XUIState)

Example 3 with XUIState

use of org.forgerock.openam.xui.XUIState in project OpenAM by OpenRock.

the class SAML2PostAuthenticationPlugin method onLogout.

@Override
public void onLogout(HttpServletRequest request, HttpServletResponse response, SSOToken ssoToken) throws AuthenticationException {
    try {
        final String ssOutEnabled = ssoToken.getProperty(SAML2Constants.SINGLE_LOGOUT);
        if (Boolean.parseBoolean(ssOutEnabled)) {
            final XUIState xuiState = InjectorHolder.getInstance(XUIState.class);
            final StringBuilder logoutLocation = new StringBuilder();
            logoutLocation.append(ssoToken.getProperty(SLO_SESSION_LOCATION));
            if (xuiState.isXUIEnabled()) {
                logoutLocation.append(ESAPI.encoder().encodeForURL(ssoToken.getProperty(SLO_SESSION_REFERENCE)));
            } else {
                logoutLocation.append(ssoToken.getProperty(SLO_SESSION_REFERENCE));
            }
            request.setAttribute(AMPostAuthProcessInterface.POST_PROCESS_LOGOUT_URL, logoutLocation.toString());
        }
    } catch (EncodingException | SSOException e) {
        //debug warning and fall through
        DEBUG.warning("Error loading SAML assertion information in memory. SLO failed for this session.", e);
    }
}
Also used : EncodingException(org.owasp.esapi.errors.EncodingException) XUIState(org.forgerock.openam.xui.XUIState) SSOException(com.iplanet.sso.SSOException)

Example 4 with XUIState

use of org.forgerock.openam.xui.XUIState in project OpenAM by OpenRock.

the class OAuth method process.

public int process(Callback[] callbacks, int state) throws LoginException {
    OAuthUtil.debugMessage("process: state = " + state);
    HttpServletRequest request = getHttpServletRequest();
    HttpServletResponse response = getHttpServletResponse();
    if (request == null) {
        OAuthUtil.debugError("OAuth.process(): The request was null, this is " + "an interactive module");
        return ISAuthConstants.LOGIN_IGNORE;
    }
    // We are being redirected back from an OAuth 2 Identity Provider
    String code = request.getParameter(PARAM_CODE);
    if (code != null) {
        OAuthUtil.debugMessage("OAuth.process(): GOT CODE: " + code);
        state = GET_OAUTH_TOKEN_STATE;
    }
    // The Proxy is used to return with a POST to the module
    proxyURL = config.getProxyURL();
    switch(state) {
        case ISAuthConstants.LOGIN_START:
            {
                config.validateConfiguration();
                serverName = request.getServerName();
                StringBuilder originalUrl = new StringBuilder();
                String requestedQuery = request.getQueryString();
                String realm = null;
                String authCookieName = AuthUtils.getAuthCookieName();
                final XUIState xuiState = InjectorHolder.getInstance(XUIState.class);
                if (xuiState.isXUIEnabled()) {
                    // When XUI is in use the request URI points to the authenticate REST endpoint, which shouldn't be
                    // presented to the end-user, hence we use the contextpath only and rely on index.html and the
                    // XUIFilter to direct the user towards the XUI.
                    originalUrl.append(request.getContextPath());
                    // the realm parameter was not present on the querystring, then we add it there.
                    if (requestedQuery != null && !requestedQuery.contains("realm=")) {
                        realm = request.getParameter("realm");
                    }
                } else {
                    //In case of legacy UI the request URI will be /openam/UI/Login, which is safe to use.
                    originalUrl.append(request.getRequestURI());
                }
                if (StringUtils.isNotEmpty(realm)) {
                    originalUrl.append("?realm=").append(URLEncDec.encode(realm));
                }
                if (requestedQuery != null) {
                    if (requestedQuery.endsWith(authCookieName + "=")) {
                        requestedQuery = requestedQuery.substring(0, requestedQuery.length() - authCookieName.length() - 1);
                    }
                    originalUrl.append(originalUrl.indexOf("?") == -1 ? '?' : '&');
                    originalUrl.append(requestedQuery);
                }
                // Find the domains for which we are configured
                Set<String> domains = AuthClientUtils.getCookieDomainsForRequest(request);
                String ProviderLogoutURL = config.getLogoutServiceUrl();
                String csrfStateTokenId = RandomStringUtils.randomAlphanumeric(32);
                String csrfState = createAuthorizationState();
                Token csrfStateToken = new Token(csrfStateTokenId, TokenType.GENERIC);
                csrfStateToken.setAttribute(CoreTokenField.STRING_ONE, csrfState);
                try {
                    ctsStore.create(csrfStateToken);
                } catch (CoreTokenException e) {
                    OAuthUtil.debugError("OAuth.process(): Authorization redirect failed to be sent because the state " + "could not be stored");
                    throw new AuthLoginException("OAuth.process(): Authorization redirect failed to be sent because " + "the state could not be stored", e);
                }
                // when retrieving the token
                for (String domain : domains) {
                    CookieUtils.addCookieToResponse(response, CookieUtils.newCookie(COOKIE_PROXY_URL, proxyURL, "/", domain));
                    CookieUtils.addCookieToResponse(response, CookieUtils.newCookie(COOKIE_ORIG_URL, originalUrl.toString(), "/", domain));
                    CookieUtils.addCookieToResponse(response, CookieUtils.newCookie(NONCE_TOKEN_ID, csrfStateTokenId, "/", domain));
                    if (ProviderLogoutURL != null && !ProviderLogoutURL.isEmpty()) {
                        CookieUtils.addCookieToResponse(response, CookieUtils.newCookie(COOKIE_LOGOUT_URL, ProviderLogoutURL, "/", domain));
                    }
                }
                // The Proxy is used to return with a POST to the module
                setUserSessionProperty(ISAuthConstants.FULL_LOGIN_URL, originalUrl.toString());
                setUserSessionProperty(SESSION_LOGOUT_BEHAVIOUR, config.getLogoutBhaviour());
                String authServiceUrl = config.getAuthServiceUrl(proxyURL, csrfState);
                OAuthUtil.debugMessage("OAuth.process(): New RedirectURL=" + authServiceUrl);
                Callback[] callbacks1 = getCallback(2);
                RedirectCallback rc = (RedirectCallback) callbacks1[0];
                RedirectCallback rcNew = new RedirectCallback(authServiceUrl, null, "GET", rc.getStatusParameter(), rc.getRedirectBackUrlCookieName());
                rcNew.setTrackingCookie(true);
                replaceCallback(2, 0, rcNew);
                return GET_OAUTH_TOKEN_STATE;
            }
        case GET_OAUTH_TOKEN_STATE:
            {
                final String csrfState;
                if (request.getParameter("jsonContent") != null) {
                    final JsonValue jval = JsonValueBuilder.toJsonValue(request.getParameter("jsonContent"));
                    csrfState = jval.get("state").asString();
                    code = jval.get(PARAM_CODE).asString();
                } else {
                    csrfState = request.getParameter("state");
                    code = request.getParameter(PARAM_CODE);
                }
                if (csrfState == null) {
                    OAuthUtil.debugError("OAuth.process(): Authorization call-back failed because there was no state " + "parameter");
                    throw new AuthLoginException(BUNDLE_NAME, "noState", null);
                }
                try {
                    Token csrfStateToken = ctsStore.read(OAuthUtil.findCookie(request, NONCE_TOKEN_ID));
                    ctsStore.deleteAsync(csrfStateToken);
                    String expectedCsrfState = csrfStateToken.getValue(CoreTokenField.STRING_ONE);
                    if (!expectedCsrfState.equals(csrfState)) {
                        OAuthUtil.debugError("OAuth.process(): Authorization call-back failed because the state parameter " + "contained an unexpected value");
                        throw new AuthLoginException(BUNDLE_NAME, "incorrectState", null);
                    }
                    // We are being redirected back from an OAuth 2 Identity Provider
                    if (code == null || code.isEmpty()) {
                        OAuthUtil.debugMessage("OAuth.process(): LOGIN_IGNORE");
                        return ISAuthConstants.LOGIN_START;
                    }
                    validateInput("code", code, "HTTPParameterValue", 2000, false);
                    OAuthUtil.debugMessage("OAuth.process(): code parameter: " + code);
                    String tokenSvcResponse = getContent(config.getTokenServiceUrl(code, proxyURL), null);
                    OAuthUtil.debugMessage("OAuth.process(): token=" + tokenSvcResponse);
                    JwtClaimsSet jwtClaims = null;
                    String idToken = null;
                    if (config.isOpenIDConnect()) {
                        idToken = extractToken(ID_TOKEN, tokenSvcResponse);
                        JwtHandler jwtHandler = new JwtHandler(jwtHandlerConfig);
                        try {
                            jwtClaims = jwtHandler.validateJwt(idToken);
                        } catch (RuntimeException | AuthLoginException e) {
                            debug.warning("Cannot validate JWT", e);
                            throw e;
                        }
                        if (!JwtHandler.isIntendedForAudience(config.getClientId(), jwtClaims)) {
                            OAuthUtil.debugError("OAuth.process(): ID token is not for this client as audience.");
                            throw new AuthLoginException(BUNDLE_NAME, "audience", null);
                        }
                    }
                    String token = extractToken(PARAM_ACCESS_TOKEN, tokenSvcResponse);
                    setUserSessionProperty(SESSION_OAUTH_TOKEN, token);
                    String profileSvcResponse = null;
                    if (StringUtils.isNotEmpty(config.getProfileServiceUrl())) {
                        profileSvcResponse = getContent(config.getProfileServiceUrl(), "Bearer " + token);
                        OAuthUtil.debugMessage("OAuth.process(): Profile Svc response: " + profileSvcResponse);
                    }
                    String realm = getRequestOrg();
                    if (realm == null) {
                        realm = "/";
                    }
                    AccountProvider accountProvider = instantiateAccountProvider();
                    AttributeMapper accountAttributeMapper = instantiateAccountMapper();
                    Map<String, Set<String>> userNames = getAttributes(profileSvcResponse, config.getAccountMapperConfig(), accountAttributeMapper, jwtClaims);
                    String user = null;
                    if (!userNames.isEmpty()) {
                        user = getUser(realm, accountProvider, userNames);
                    }
                    if (user == null && !config.getCreateAccountFlag()) {
                        authenticatedUser = getDynamicUser(userNames);
                        if (authenticatedUser != null) {
                            if (config.getSaveAttributesToSessionFlag()) {
                                Map<String, Set<String>> attributes = getAttributesMap(profileSvcResponse, jwtClaims);
                                saveAttributes(attributes);
                            }
                            OAuthUtil.debugMessage("OAuth.process(): LOGIN_SUCCEED " + "with user " + authenticatedUser);
                            storeUsernamePasswd(authenticatedUser, null);
                            return ISAuthConstants.LOGIN_SUCCEED;
                        } else {
                            throw new AuthLoginException("No user mapped!");
                        }
                    }
                    if (user == null && config.getCreateAccountFlag()) {
                        if (config.getPromptPasswordFlag()) {
                            setUserSessionProperty(PROFILE_SERVICE_RESPONSE, profileSvcResponse);
                            if (config.isOpenIDConnect()) {
                                setUserSessionProperty(OPENID_TOKEN, idToken);
                            }
                            return SET_PASSWORD_STATE;
                        } else {
                            authenticatedUser = provisionAccountNow(accountProvider, realm, profileSvcResponse, getRandomData(), jwtClaims);
                            if (authenticatedUser != null) {
                                OAuthUtil.debugMessage("User created: " + authenticatedUser);
                                storeUsernamePasswd(authenticatedUser, null);
                                return ISAuthConstants.LOGIN_SUCCEED;
                            } else {
                                return ISAuthConstants.LOGIN_IGNORE;
                            }
                        }
                    }
                    if (user != null) {
                        authenticatedUser = user;
                        OAuthUtil.debugMessage("OAuth.process(): LOGIN_SUCCEED " + "with user " + authenticatedUser);
                        if (config.getSaveAttributesToSessionFlag()) {
                            Map<String, Set<String>> attributes = getAttributesMap(profileSvcResponse, jwtClaims);
                            saveAttributes(attributes);
                        }
                        storeUsernamePasswd(authenticatedUser, null);
                        return ISAuthConstants.LOGIN_SUCCEED;
                    }
                } catch (JSONException je) {
                    OAuthUtil.debugError("OAuth.process(): JSONException: " + je.getMessage());
                    throw new AuthLoginException(BUNDLE_NAME, "json", null, je);
                } catch (SSOException ssoe) {
                    OAuthUtil.debugError("OAuth.process(): SSOException: " + ssoe.getMessage());
                    throw new AuthLoginException(BUNDLE_NAME, "ssoe", null, ssoe);
                } catch (IdRepoException ire) {
                    OAuthUtil.debugError("OAuth.process(): IdRepoException: " + ire.getMessage());
                    throw new AuthLoginException(BUNDLE_NAME, "ire", null, ire);
                } catch (CoreTokenException e) {
                    OAuthUtil.debugError("OAuth.process(): Authorization call-back failed because the state parameter " + "contained an unexpected value");
                    throw new AuthLoginException(BUNDLE_NAME, "incorrectState", null, e);
                }
                break;
            }
        case SET_PASSWORD_STATE:
            {
                if (!config.getCreateAccountFlag()) {
                    return ISAuthConstants.LOGIN_IGNORE;
                }
                userPassword = request.getParameter(PARAM_TOKEN1);
                validateInput(PARAM_TOKEN1, userPassword, "HTTPParameterValue", 512, false);
                String userPassword2 = request.getParameter(PARAM_TOKEN2);
                validateInput(PARAM_TOKEN2, userPassword2, "HTTPParameterValue", 512, false);
                if (!userPassword.equals(userPassword2)) {
                    OAuthUtil.debugWarning("OAuth.process(): Passwords did not match!");
                    return SET_PASSWORD_STATE;
                }
                String terms = request.getParameter("terms");
                if (!terms.equalsIgnoreCase("accept")) {
                    return SET_PASSWORD_STATE;
                }
                String profileSvcResponse = getUserSessionProperty("ATTRIBUTES");
                data = getRandomData();
                String mail = getMail(profileSvcResponse, config.getMailAttribute());
                OAuthUtil.debugMessage("Mail found = " + mail);
                try {
                    OAuthUtil.sendEmail(config.getEmailFrom(), mail, data, config.getSMTPConfig(), bundle, proxyURL);
                } catch (NoEmailSentException ex) {
                    OAuthUtil.debugError("No mail sent due to error", ex);
                    throw new AuthLoginException("Aborting authentication, because " + "the mail could not be sent due to a mail sending error");
                }
                OAuthUtil.debugMessage("User to be created, we need to activate: " + data);
                return CREATE_USER_STATE;
            }
        case CREATE_USER_STATE:
            {
                String activation = request.getParameter(PARAM_ACTIVATION);
                validateInput(PARAM_ACTIVATION, activation, "HTTPParameterValue", 512, false);
                OAuthUtil.debugMessage("code entered by the user: " + activation);
                if (activation == null || activation.isEmpty() || !activation.trim().equals(data.trim())) {
                    return CREATE_USER_STATE;
                }
                String profileSvcResponse = getUserSessionProperty(PROFILE_SERVICE_RESPONSE);
                String idToken = getUserSessionProperty(ID_TOKEN);
                String realm = getRequestOrg();
                if (realm == null) {
                    realm = "/";
                }
                OAuthUtil.debugMessage("Got Attributes: " + profileSvcResponse);
                AccountProvider accountProvider = instantiateAccountProvider();
                JwtClaimsSet jwtClaims = null;
                if (idToken != null) {
                    jwtClaims = new JwtHandler(jwtHandlerConfig).getJwtClaims(idToken);
                }
                authenticatedUser = provisionAccountNow(accountProvider, realm, profileSvcResponse, userPassword, jwtClaims);
                if (authenticatedUser != null) {
                    OAuthUtil.debugMessage("User created: " + authenticatedUser);
                    storeUsernamePasswd(authenticatedUser, null);
                    return ISAuthConstants.LOGIN_SUCCEED;
                } else {
                    return ISAuthConstants.LOGIN_IGNORE;
                }
            }
        default:
            {
                OAuthUtil.debugError("OAuth.process(): Illegal State");
                return ISAuthConstants.LOGIN_IGNORE;
            }
    }
    throw new AuthLoginException(BUNDLE_NAME, "unknownState", null);
}
Also used : RedirectCallback(com.sun.identity.authentication.spi.RedirectCallback) Set(java.util.Set) JwtClaimsSet(org.forgerock.json.jose.jwt.JwtClaimsSet) JsonValue(org.forgerock.json.JsonValue) IdRepoException(com.sun.identity.idm.IdRepoException) HttpServletResponse(javax.servlet.http.HttpServletResponse) CoreTokenException(org.forgerock.openam.cts.exceptions.CoreTokenException) AuthLoginException(com.sun.identity.authentication.spi.AuthLoginException) JSONException(org.json.JSONException) Token(org.forgerock.openam.cts.api.tokens.Token) SSOException(com.iplanet.sso.SSOException) HttpServletRequest(javax.servlet.http.HttpServletRequest) JwtClaimsSet(org.forgerock.json.jose.jwt.JwtClaimsSet) AttributeMapper(org.forgerock.openam.authentication.modules.common.mapping.AttributeMapper) JwtHandler(org.forgerock.openam.authentication.modules.oidc.JwtHandler) XUIState(org.forgerock.openam.xui.XUIState) AccountProvider(org.forgerock.openam.authentication.modules.common.mapping.AccountProvider) Map(java.util.Map) HashMap(java.util.HashMap)

Example 5 with XUIState

use of org.forgerock.openam.xui.XUIState in project OpenAM by OpenRock.

the class OAuthProxy method continueAuthentication.

public static void continueAuthentication(HttpServletRequest req, HttpServletResponse res, PrintWriter out) {
    OAuthUtil.debugMessage("toPostForm: started");
    String action = OAuthUtil.findCookie(req, COOKIE_ORIG_URL);
    if (OAuthUtil.isEmpty(action)) {
        out.println(getError("Request not valid !"));
        return;
    }
    Map<String, String[]> params = req.getParameterMap();
    if (!params.containsKey(PARAM_CODE) && !params.containsKey(PARAM_ACTIVATION)) {
        OAuthUtil.debugError("OAuthProxy.toPostForm: Parameters " + PARAM_CODE + " or " + PARAM_ACTIVATION + " were not present in the request");
        out.println(getError("Request not valid, perhaps a permission problem"));
        return;
    }
    StringBuilder html = new StringBuilder();
    try {
        String code = req.getParameter(PARAM_CODE);
        if (code != null && !OAuthUtil.isEmpty(code)) {
            if (!ESAPI.validator().isValidInput(PARAM_CODE, code, "HTTPParameterValue", 2000, true)) {
                OAuthUtil.debugError("OAuthProxy.toPostForm: Parameter " + PARAM_CODE + " is not valid!! : " + code);
                out.println(getError("Invalid authorization code"));
                return;
            }
        }
        if (action.contains("?")) {
            action += "&" + req.getQueryString();
        } else {
            action += "?" + req.getQueryString();
        }
        XUIState xuiState = InjectorHolder.getInstance(XUIState.class);
        if (xuiState.isXUIEnabled()) {
            // OAuthProxy.jsp should be always accessed via GET, hence the querystring should contain all important
            // parameters already.
            res.sendRedirect(action);
            return;
        } else {
            action = ESAPI.encoder().encodeForHTMLAttribute(action);
            String onLoad = "document.postform.submit()";
            html.append("<html>\n").append("<body onLoad=\"").append(onLoad).append("\">\n");
            html.append("<form name=\"postform\" action=\"").append(action).append("\" method=\"post\">\n");
            String activation = req.getParameter(PARAM_ACTIVATION);
            if (activation != null && !OAuthUtil.isEmpty(activation)) {
                if (ESAPI.validator().isValidInput(PARAM_ACTIVATION, activation, "HTTPParameterValue", 512, true)) {
                    html.append(input(PARAM_ACTIVATION, activation));
                } else {
                    OAuthUtil.debugError("OAuthProxy.toPostForm: Parameter " + PARAM_ACTIVATION + " is not valid!! : " + activation);
                    out.println(getError("Request not valid"));
                    return;
                }
            }
        }
    } catch (Exception e) {
        out.println(getError(e.getMessage()));
        return;
    }
    html.append("<noscript>\n<center>\n");
    html.append("<p>Your browser does not have JavaScript enabled, you must click" + " the button below to continue</p>\n");
    html.append("<input type=\"submit\" value=\"submit\" />\n");
    html.append("</center>\n</noscript>\n");
    html.append("</form>\n").append("</body>\n").append("</html>\n");
    OAuthUtil.debugMessage("OAuthProxy.toPostForm: form html:\n" + html);
    OAuthUtil.debugMessage("OAuthProxy.toPostForm: removing cookie " + COOKIE_ORIG_URL);
    for (String cookieDomain : AuthClientUtils.getCookieDomainsForRequest(req)) {
        CookieUtils.addCookieToResponse(res, CookieUtils.newCookie(COOKIE_ORIG_URL, "", 0, "/", cookieDomain));
    }
    out.println(html.toString());
}
Also used : XUIState(org.forgerock.openam.xui.XUIState)

Aggregations

XUIState (org.forgerock.openam.xui.XUIState)5 SSOException (com.iplanet.sso.SSOException)2 AuthLoginException (com.sun.identity.authentication.spi.AuthLoginException)1 RedirectCallback (com.sun.identity.authentication.spi.RedirectCallback)1 IdRepoException (com.sun.identity.idm.IdRepoException)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 Set (java.util.Set)1 HttpServletRequest (javax.servlet.http.HttpServletRequest)1 HttpServletResponse (javax.servlet.http.HttpServletResponse)1 JsonValue (org.forgerock.json.JsonValue)1 JwtClaimsSet (org.forgerock.json.jose.jwt.JwtClaimsSet)1 AccountProvider (org.forgerock.openam.authentication.modules.common.mapping.AccountProvider)1 AttributeMapper (org.forgerock.openam.authentication.modules.common.mapping.AttributeMapper)1 JwtHandler (org.forgerock.openam.authentication.modules.oidc.JwtHandler)1 Token (org.forgerock.openam.cts.api.tokens.Token)1 CoreTokenException (org.forgerock.openam.cts.exceptions.CoreTokenException)1 JSONException (org.json.JSONException)1 EncodingException (org.owasp.esapi.errors.EncodingException)1