Search in sources :

Example 61 with PwmSession

use of password.pwm.http.PwmSession in project pwm by pwm-project.

the class OAuthConsumerServlet method processAction.

@Override
@SuppressWarnings("checkstyle:MethodLength")
protected void processAction(final PwmRequest pwmRequest) throws ServletException, IOException, PwmUnrecoverableException {
    final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
    final Configuration config = pwmRequest.getConfig();
    final PwmSession pwmSession = pwmRequest.getPwmSession();
    final boolean userIsAuthenticated = pwmSession.isAuthenticated();
    final Optional<OAuthRequestState> oAuthRequestState = OAuthMachine.readOAuthRequestState(pwmRequest);
    final OAuthUseCase oAuthUseCaseCase = oAuthRequestState.isPresent() ? oAuthRequestState.get().getoAuthState().getUseCase() : OAuthUseCase.Authentication;
    LOGGER.trace(pwmRequest, "processing oauth return request, useCase=" + oAuthUseCaseCase + ", incoming oAuthRequestState=" + (oAuthRequestState.isPresent() ? JsonUtil.serialize(oAuthRequestState.get()) : "none"));
    // make sure it's okay to be processing this request.
    switch(oAuthUseCaseCase) {
        case Authentication:
            {
                if (!userIsAuthenticated && !pwmSession.getSessionStateBean().isOauthInProgress()) {
                    if (oAuthRequestState.isPresent()) {
                        final String nextUrl = oAuthRequestState.get().getoAuthState().getNextUrl();
                        LOGGER.debug(pwmSession, "received unrecognized oauth response, ignoring authcode and redirecting to embedded next url: " + nextUrl);
                        pwmRequest.sendRedirect(nextUrl);
                        return;
                    }
                    final String errorMsg = "oauth consumer reached, but oauth authentication has not yet been initiated.";
                    final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_OAUTH_ERROR, errorMsg);
                    pwmRequest.respondWithError(errorInformation);
                    LOGGER.error(pwmSession, errorMsg);
                    return;
                }
            }
            break;
        default:
            // for non-auth requests its okay to continue
            break;
    }
    // check if there is an "error" on the request sent from the oauth server., if there is then halt.
    {
        final String oauthRequestError = pwmRequest.readParameterAsString("error");
        if (oauthRequestError != null && !oauthRequestError.isEmpty()) {
            final String errorMsg = "incoming request from remote oauth server is indicating an error: " + oauthRequestError;
            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_OAUTH_ERROR, errorMsg, "Remote Error: " + oauthRequestError, null);
            LOGGER.error(pwmSession, errorMsg);
            pwmRequest.respondWithError(errorInformation);
            return;
        }
    }
    // check if user is already authenticated - shouldn't be in nominal usage.
    if (userIsAuthenticated) {
        switch(oAuthUseCaseCase) {
            case Authentication:
                LOGGER.debug(pwmSession, "oauth consumer reached, but user is already authenticated; will proceed and verify authcode matches current user identity.");
                break;
            case ForgottenPassword:
                final String errorMsg = "oauth consumer reached via " + OAuthUseCase.ForgottenPassword + ", but user is already authenticated";
                final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_OAUTH_ERROR, errorMsg);
                pwmRequest.respondWithError(errorInformation);
                LOGGER.error(pwmSession, errorMsg);
                return;
            default:
                JavaHelper.unhandledSwitchStatement(oAuthUseCaseCase);
        }
    }
    // mark the inprogress flag to false, if we get this far and fail user needs to start over.
    pwmSession.getSessionStateBean().setOauthInProgress(false);
    if (!oAuthRequestState.isPresent()) {
        final String errorMsg = "state parameter is missing from oauth request";
        final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_OAUTH_ERROR, errorMsg);
        LOGGER.error(pwmSession, errorMsg);
        pwmRequest.respondWithError(errorInformation);
        return;
    }
    final OAuthState oauthState = oAuthRequestState.get().getoAuthState();
    final OAuthSettings oAuthSettings = makeOAuthSettings(pwmRequest, oauthState);
    final OAuthMachine oAuthMachine = new OAuthMachine(oAuthSettings);
    // make sure request was initiated in users current session
    if (!oAuthRequestState.get().isSessionMatch()) {
        try {
            switch(oAuthUseCaseCase) {
                case Authentication:
                    LOGGER.debug(pwmSession, "oauth consumer reached but response is not for a request issued during the current session," + " will redirect back to oauth server for verification update");
                    final String nextURL = oauthState.getNextUrl();
                    oAuthMachine.redirectUserToOAuthServer(pwmRequest, nextURL, null, null);
                    return;
                case ForgottenPassword:
                    LOGGER.debug(pwmSession, "oauth consumer reached but response is not for a request issued during the current session," + " will redirect back to forgotten password servlet");
                    pwmRequest.sendRedirect(PwmServletDefinition.ForgottenPassword);
                    return;
                default:
                    JavaHelper.unhandledSwitchStatement(oAuthUseCaseCase);
            }
        } catch (PwmUnrecoverableException e) {
            final String errorMsg = "unexpected error redirecting user to oauth page: " + e.toString();
            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_OAUTH_ERROR, errorMsg);
            setLastError(pwmRequest, errorInformation);
            LOGGER.error(errorInformation.toDebugStr());
        }
    }
    final String requestCodeStr = pwmRequest.readParameterAsString(config.readAppProperty(AppProperty.HTTP_PARAM_OAUTH_CODE));
    LOGGER.trace(pwmSession, "received code from oauth server: " + requestCodeStr);
    final OAuthResolveResults resolveResults;
    try {
        resolveResults = oAuthMachine.makeOAuthResolveRequest(pwmRequest, requestCodeStr);
    } catch (PwmException e) {
        final String errorMsg = "unexpected error communicating with oauth server: " + e.toString();
        final ErrorInformation errorInformation = new ErrorInformation(e.getError(), errorMsg);
        setLastError(pwmRequest, errorInformation);
        LOGGER.error(errorInformation.toDebugStr());
        return;
    }
    if (resolveResults == null || resolveResults.getAccessToken() == null || resolveResults.getAccessToken().isEmpty()) {
        final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_OAUTH_ERROR, "browser redirect from oauth server did not include an access token");
        LOGGER.error(pwmRequest, errorInformation);
        pwmRequest.respondWithError(errorInformation);
        return;
    }
    if (resolveResults.getExpiresSeconds() > 0) {
        if (resolveResults.getRefreshToken() == null || resolveResults.getRefreshToken().isEmpty()) {
            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_OAUTH_ERROR, "oauth server gave expiration for access token, but did not provide a refresh token");
            LOGGER.error(pwmRequest, errorInformation);
            pwmRequest.respondWithError(errorInformation);
            return;
        }
    }
    final String oauthSuppliedUsername;
    {
        final String getAttributeResponseBodyStr = oAuthMachine.makeOAuthGetAttributeRequest(pwmRequest, resolveResults.getAccessToken());
        final Map<String, String> getAttributeResultValues = JsonUtil.deserializeStringMap(getAttributeResponseBodyStr);
        oauthSuppliedUsername = getAttributeResultValues.get(oAuthSettings.getDnAttributeName());
        if (oauthSuppliedUsername == null || oauthSuppliedUsername.isEmpty()) {
            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_OAUTH_ERROR, "OAuth server did not respond with an username attribute value");
            LOGGER.error(pwmRequest, errorInformation);
            pwmRequest.respondWithError(errorInformation);
            return;
        }
    }
    LOGGER.debug(pwmSession, "received user login id value from OAuth server: " + oauthSuppliedUsername);
    if (oAuthUseCaseCase == OAuthUseCase.ForgottenPassword) {
        redirectToForgottenPasswordServlet(pwmRequest, oauthSuppliedUsername);
        return;
    }
    if (userIsAuthenticated) {
        try {
            final UserSearchEngine userSearchEngine = pwmApplication.getUserSearchEngine();
            final UserIdentity resolvedIdentity = userSearchEngine.resolveUsername(oauthSuppliedUsername, null, null, pwmSession.getLabel());
            if (resolvedIdentity != null && resolvedIdentity.canonicalEquals(pwmSession.getUserInfo().getUserIdentity(), pwmApplication)) {
                LOGGER.debug(pwmSession, "verified incoming oauth code for already authenticated session does resolve to same as logged in user");
            } else {
                final String errorMsg = "incoming oauth code for already authenticated session does not resolve to same as logged in user ";
                final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_OAUTH_ERROR, errorMsg);
                LOGGER.error(pwmSession, errorMsg);
                pwmRequest.respondWithError(errorInformation);
                pwmSession.unauthenticateUser(pwmRequest);
                return;
            }
        } catch (PwmOperationalException e) {
            final String errorMsg = "error while examining incoming oauth code for already authenticated session: " + e.getMessage();
            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_OAUTH_ERROR, errorMsg);
            LOGGER.error(pwmSession, errorMsg);
            pwmRequest.respondWithError(errorInformation);
            return;
        }
    }
    try {
        if (!userIsAuthenticated) {
            final SessionAuthenticator sessionAuthenticator = new SessionAuthenticator(pwmApplication, pwmSession, PwmAuthenticationSource.OAUTH);
            sessionAuthenticator.authUserWithUnknownPassword(oauthSuppliedUsername, AuthenticationType.AUTH_WITHOUT_PASSWORD);
        }
        // recycle the session to prevent session fixation attack.
        pwmRequest.getPwmSession().getSessionStateBean().setSessionIdRecycleNeeded(true);
        // forward to nextUrl
        final String nextUrl = oauthState.getNextUrl();
        LOGGER.debug(pwmSession, "oauth authentication completed, redirecting to originally requested URL: " + nextUrl);
        pwmRequest.sendRedirect(nextUrl);
    } catch (PwmException e) {
        LOGGER.error(pwmSession, "error during OAuth authentication attempt: " + e.getMessage());
        final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_OAUTH_ERROR, e.getMessage());
        pwmRequest.respondWithError(errorInformation);
        return;
    }
    LOGGER.trace(pwmSession, "OAuth login sequence successfully completed");
}
Also used : PwmApplication(password.pwm.PwmApplication) Configuration(password.pwm.config.Configuration) SessionAuthenticator(password.pwm.ldap.auth.SessionAuthenticator) UserSearchEngine(password.pwm.ldap.search.UserSearchEngine) UserIdentity(password.pwm.bean.UserIdentity) PwmUnrecoverableException(password.pwm.error.PwmUnrecoverableException) PwmOperationalException(password.pwm.error.PwmOperationalException) PwmException(password.pwm.error.PwmException) ErrorInformation(password.pwm.error.ErrorInformation) PwmSession(password.pwm.http.PwmSession) HashMap(java.util.HashMap) Map(java.util.Map)

Example 62 with PwmSession

use of password.pwm.http.PwmSession in project pwm by pwm-project.

the class HelpdeskServlet method restDeleteUserRequest.

@ActionHandler(action = "deleteUser")
private ProcessStatus restDeleteUserRequest(final PwmRequest pwmRequest) throws ChaiUnavailableException, PwmUnrecoverableException, IOException, ServletException {
    final HelpdeskProfile helpdeskProfile = getHelpdeskProfile(pwmRequest);
    final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
    final PwmSession pwmSession = pwmRequest.getPwmSession();
    final String userKey = pwmRequest.readParameterAsString(PwmConstants.PARAM_USERKEY, PwmHttpRequestWrapper.Flag.BypassValidation);
    if (userKey.length() < 1) {
        final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_MISSING_PARAMETER, PwmConstants.PARAM_USERKEY + " parameter is missing");
        setLastError(pwmRequest, errorInformation);
        pwmRequest.respondWithError(errorInformation, false);
        return ProcessStatus.Halt;
    }
    final UserIdentity userIdentity = UserIdentity.fromKey(userKey, pwmApplication);
    LOGGER.info(pwmSession, "received deleteUser request by " + pwmSession.getUserInfo().getUserIdentity().toString() + " for user " + userIdentity.toString());
    // check if user should be seen by actor
    HelpdeskServletUtil.checkIfUserIdentityViewable(pwmRequest, helpdeskProfile, userIdentity);
    // read the userID for later logging.
    String userID = null;
    try {
        userID = pwmSession.getUserInfo().getUsername();
    } catch (PwmUnrecoverableException e) {
        LOGGER.warn(pwmSession, "unable to read username of deleted user while creating audit record");
    }
    // execute user delete operation
    final ChaiProvider provider = helpdeskProfile.readSettingAsBoolean(PwmSetting.HELPDESK_USE_PROXY) ? pwmApplication.getProxyChaiProvider(userIdentity.getLdapProfileID()) : pwmSession.getSessionManager().getChaiProvider();
    try {
        provider.deleteEntry(userIdentity.getUserDN());
    } catch (ChaiOperationException e) {
        final String errorMsg = "error while attempting to delete user " + userIdentity.toString() + ", error: " + e.getMessage();
        final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_UNKNOWN, errorMsg);
        LOGGER.debug(pwmRequest, errorMsg);
        pwmRequest.outputJsonResult(RestResultBean.fromError(errorInformation, pwmRequest));
        return ProcessStatus.Halt;
    }
    // mark the event log
    {
        // normally the audit record builder reads the userID while constructing the record, but because the target user is already deleted,
        // it will be included here explicitly.
        final AuditRecordFactory.AuditUserDefinition auditUserDefinition = new AuditRecordFactory.AuditUserDefinition(userID, userIdentity.getUserDN(), userIdentity.getLdapProfileID());
        final HelpdeskAuditRecord auditRecord = new AuditRecordFactory(pwmRequest).createHelpdeskAuditRecord(AuditEvent.HELPDESK_DELETE_USER, pwmSession.getUserInfo().getUserIdentity(), null, auditUserDefinition, pwmSession.getSessionStateBean().getSrcAddress(), pwmSession.getSessionStateBean().getSrcHostname());
        pwmApplication.getAuditManager().submit(auditRecord);
    }
    LOGGER.info(pwmSession, "user " + userIdentity + " has been deleted");
    final RestResultBean restResultBean = RestResultBean.forSuccessMessage(pwmRequest, Message.Success_Unknown);
    pwmRequest.outputJsonResult(restResultBean);
    return ProcessStatus.Halt;
}
Also used : PwmApplication(password.pwm.PwmApplication) UserIdentity(password.pwm.bean.UserIdentity) HelpdeskProfile(password.pwm.config.profile.HelpdeskProfile) PwmUnrecoverableException(password.pwm.error.PwmUnrecoverableException) HelpdeskAuditRecord(password.pwm.svc.event.HelpdeskAuditRecord) ErrorInformation(password.pwm.error.ErrorInformation) AuditRecordFactory(password.pwm.svc.event.AuditRecordFactory) ChaiProvider(com.novell.ldapchai.provider.ChaiProvider) ChaiOperationException(com.novell.ldapchai.exception.ChaiOperationException) PwmSession(password.pwm.http.PwmSession) RestResultBean(password.pwm.ws.server.RestResultBean)

Example 63 with PwmSession

use of password.pwm.http.PwmSession in project pwm by pwm-project.

the class ChangePasswordServlet method preProcessCheck.

@Override
public ProcessStatus preProcessCheck(final PwmRequest pwmRequest) throws PwmUnrecoverableException, IOException, ServletException {
    final PwmSession pwmSession = pwmRequest.getPwmSession();
    final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
    final ChangePasswordBean changePasswordBean = pwmApplication.getSessionStateService().getBean(pwmRequest, ChangePasswordBean.class);
    if (pwmSession.getLoginInfoBean().getType() == AuthenticationType.AUTH_WITHOUT_PASSWORD) {
        throw new PwmUnrecoverableException(PwmError.ERROR_PASSWORD_REQUIRED);
    }
    if (!pwmRequest.isAuthenticated()) {
        pwmRequest.respondWithError(PwmError.ERROR_AUTHENTICATION_REQUIRED.toInfo());
        LOGGER.debug(pwmRequest, "rejecting action request for unauthenticated session");
        return ProcessStatus.Halt;
    }
    if (ChangePasswordServletUtil.determineIfCurrentPasswordRequired(pwmApplication, pwmSession)) {
        changePasswordBean.setCurrentPasswordRequired(true);
    }
    if (!pwmSession.getSessionManager().checkPermission(pwmApplication, Permission.CHANGE_PASSWORD)) {
        pwmRequest.respondWithError(PwmError.ERROR_UNAUTHORIZED.toInfo());
        return ProcessStatus.Halt;
    }
    ChangePasswordServletUtil.checkMinimumLifetime(pwmApplication, pwmSession, changePasswordBean, pwmSession.getUserInfo());
    return ProcessStatus.Continue;
}
Also used : ChangePasswordBean(password.pwm.http.bean.ChangePasswordBean) PwmApplication(password.pwm.PwmApplication) PwmUnrecoverableException(password.pwm.error.PwmUnrecoverableException) PwmSession(password.pwm.http.PwmSession)

Example 64 with PwmSession

use of password.pwm.http.PwmSession in project pwm by pwm-project.

the class CommandServlet method checkIfUserAuthenticated.

private static boolean checkIfUserAuthenticated(final PwmRequest pwmRequest) throws ChaiUnavailableException, IOException, ServletException, PwmUnrecoverableException {
    final PwmSession pwmSession = pwmRequest.getPwmSession();
    if (!pwmRequest.isAuthenticated()) {
        final String action = pwmRequest.readParameterAsString(PwmConstants.PARAM_ACTION_REQUEST);
        LOGGER.info(pwmSession, "authentication required for " + action);
        pwmRequest.respondWithError(PwmError.ERROR_AUTHENTICATION_REQUIRED.toInfo());
        return false;
    }
    return true;
}
Also used : PwmSession(password.pwm.http.PwmSession)

Example 65 with PwmSession

use of password.pwm.http.PwmSession in project pwm by pwm-project.

the class LogoutServlet method nextStep.

public void nextStep(final PwmRequest pwmRequest) throws PwmUnrecoverableException, IOException {
    final String nextUrl;
    if (!pwmRequest.getPwmSession().getSessionStateBean().isPasswordModified()) {
        nextUrl = readAndValidateNextUrlParameter(pwmRequest).orElse(null);
    } else {
        nextUrl = null;
    }
    // no process action so this is the first time through this method;
    final boolean authenticated = pwmRequest.isAuthenticated();
    final boolean logoutDueToIdle = Boolean.parseBoolean(pwmRequest.readParameterAsString(PARAM_IDLE));
    String debugMsg = "processing " + (authenticated ? "authenticated" : "unauthenticated") + " logout request";
    if (logoutDueToIdle) {
        debugMsg += " due to client idle timeout";
    }
    LOGGER.debug(pwmRequest, debugMsg);
    final PwmSession pwmSession = pwmRequest.getPwmSession();
    final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
    pwmSession.unauthenticateUser(pwmRequest);
    {
        // if there is a session url, then use that to do a redirect.
        final String sessionLogoutURL = pwmSession.getSessionStateBean().getLogoutURL();
        if (sessionLogoutURL != null && sessionLogoutURL.length() > 0) {
            LOGGER.trace(pwmSession, "redirecting user to session parameter set logout url: " + sessionLogoutURL);
            pwmRequest.sendRedirect(sessionLogoutURL);
            pwmRequest.invalidateSession();
            return;
        }
    }
    {
        // if the logout url hasn't been set then try seeing if one has been configured.
        final String configuredLogoutURL = pwmApplication.getConfig().readSettingAsString(PwmSetting.URL_LOGOUT);
        if (configuredLogoutURL != null && configuredLogoutURL.length() > 0) {
            // construct params
            final Map<String, String> logoutUrlParameters = new LinkedHashMap<>();
            logoutUrlParameters.put(PARAM_IDLE, String.valueOf(logoutDueToIdle));
            logoutUrlParameters.put(PARAM_PASSWORD_MODIFIED, String.valueOf(pwmSession.getSessionStateBean().isPasswordModified()));
            logoutUrlParameters.put(PARAM_PUBLIC_ONLY, String.valueOf(!pwmSession.getSessionStateBean().isPrivateUrlAccessed()));
            {
                final String sessionForwardURL = pwmSession.getSessionStateBean().getForwardURL();
                if (sessionForwardURL != null && sessionForwardURL.length() > 0) {
                    logoutUrlParameters.put(pwmApplication.getConfig().readAppProperty(AppProperty.HTTP_PARAM_NAME_FORWARD_URL), sessionForwardURL);
                }
            }
            final String logoutURL = PwmURL.appendAndEncodeUrlParameters(configuredLogoutURL, logoutUrlParameters);
            LOGGER.trace(pwmSession, "redirecting user to configured logout url:" + logoutURL);
            pwmRequest.sendRedirect(logoutURL);
            pwmRequest.invalidateSession();
            return;
        }
    }
    // if we didn't go anywhere yet, then show the pwm logout jsp
    final LogoutAction nextAction = authenticated ? LogoutAction.showLogout : LogoutAction.showTimeout;
    final Map<String, String> logoutUrlParameters = new LinkedHashMap<>();
    logoutUrlParameters.put(PwmConstants.PARAM_ACTION_REQUEST, nextAction.toString());
    if (nextUrl != null) {
        logoutUrlParameters.put(PARAM_URL, nextUrl);
    }
    final String logoutURL = PwmURL.appendAndEncodeUrlParameters(pwmRequest.getContextPath() + PwmServletDefinition.Logout.servletUrl(), logoutUrlParameters);
    pwmRequest.invalidateSession();
    pwmRequest.sendRedirect(logoutURL);
}
Also used : PwmApplication(password.pwm.PwmApplication) PwmSession(password.pwm.http.PwmSession) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap)

Aggregations

PwmSession (password.pwm.http.PwmSession)74 PwmApplication (password.pwm.PwmApplication)55 ErrorInformation (password.pwm.error.ErrorInformation)38 PwmUnrecoverableException (password.pwm.error.PwmUnrecoverableException)30 PwmOperationalException (password.pwm.error.PwmOperationalException)29 Configuration (password.pwm.config.Configuration)21 UserIdentity (password.pwm.bean.UserIdentity)20 FormConfiguration (password.pwm.config.value.data.FormConfiguration)19 PwmException (password.pwm.error.PwmException)14 ChaiUser (com.novell.ldapchai.ChaiUser)12 ActionConfiguration (password.pwm.config.value.data.ActionConfiguration)12 UserInfo (password.pwm.ldap.UserInfo)12 SearchConfiguration (password.pwm.ldap.search.SearchConfiguration)11 ChaiOperationException (com.novell.ldapchai.exception.ChaiOperationException)9 ChaiUnavailableException (com.novell.ldapchai.exception.ChaiUnavailableException)9 IOException (java.io.IOException)9 Instant (java.time.Instant)9 RestResultBean (password.pwm.ws.server.RestResultBean)9 ServletException (javax.servlet.ServletException)8 MacroMachine (password.pwm.util.macro.MacroMachine)8