Search in sources :

Example 1 with HandlerResultImpl

use of org.codice.ddf.security.handler.HandlerResultImpl in project ddf by codice.

the class OidcHandler method getNormalizedToken.

/**
 * Handler implementing OIDC authentication.
 *
 * @param request http request to obtain attributes from and to pass into any local filter chains
 *     required
 * @param response http response to return http responses or redirects
 * @param chain original filter chain (should not be called from your handler)
 * @param resolve flag with true implying that credentials should be obtained, false implying
 *     return if no credentials are found.
 * @return result of handling this request - status and optional tokens
 * @throws AuthenticationFailureException
 */
@Override
public HandlerResult getNormalizedToken(ServletRequest request, ServletResponse response, SecurityFilterChain chain, boolean resolve) throws AuthenticationFailureException {
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    HttpServletResponse httpResponse = (HttpServletResponse) response;
    if (httpRequest.getMethod().equals("HEAD")) {
        return processHeadRequest(httpResponse);
    }
    LOGGER.debug("Doing Oidc authentication and authorization for path {}.", httpRequest.getContextPath());
    JEESessionStore sessionStore = new JEESessionStore();
    JEEContext jeeContext = new JEEContext(httpRequest, httpResponse, sessionStore);
    StringBuffer requestUrlBuffer = httpRequest.getRequestURL();
    requestUrlBuffer.append(httpRequest.getQueryString() == null ? "" : "?" + httpRequest.getQueryString());
    String requestUrl = requestUrlBuffer.toString();
    String ipAddress = httpRequest.getRemoteAddr();
    OidcClient<OidcConfiguration> oidcClient = configuration.getOidcClient(requestUrl);
    OidcCredentials credentials;
    boolean isMachine = userAgentIsNotBrowser(httpRequest);
    if (isMachine) {
        LOGGER.debug("The Oidc Handler does not handle machine to machine requests. Continuing to other handlers.");
        return noActionResult;
    } else {
        // check for Authorization Code Flow, Implicit Flow, or Hybrid Flow credentials
        try {
            credentials = getCredentialsFromRequest(oidcClient, jeeContext);
        } catch (IllegalArgumentException e) {
            LOGGER.debug(e.getMessage(), e);
            LOGGER.error("Problem with the Oidc Handler's configuration. " + "Check the Oidc Handler configuration in the admin console.");
            return noActionResult;
        } catch (TechnicalException e) {
            LOGGER.debug("Problem extracting Oidc credentials from incoming user request.", e);
            return redirectForCredentials(oidcClient, jeeContext, requestUrl);
        }
    }
    // if the request has credentials, process it
    if (credentials != null && (credentials.getCode() != null || credentials.getAccessToken() != null || credentials.getIdToken() != null)) {
        LOGGER.info("Oidc credentials found/retrieved. Saving to session and continuing filter chain.");
        OidcAuthenticationToken token = new OidcAuthenticationToken(credentials, jeeContext, ipAddress);
        HandlerResult handlerResult = new HandlerResultImpl(Status.COMPLETED, token);
        handlerResult.setSource(SOURCE);
        return handlerResult;
    } else {
        // the user agent request didn't have credentials, redirect and go get some
        LOGGER.info("No credentials found on user-agent request. " + "Redirecting user-agent to IdP for credentials.");
        return redirectForCredentials(oidcClient, jeeContext, requestUrl);
    }
}
Also used : TechnicalException(org.pac4j.core.exception.TechnicalException) HandlerResultImpl(org.codice.ddf.security.handler.HandlerResultImpl) JEEContext(org.pac4j.core.context.JEEContext) OidcAuthenticationToken(org.codice.ddf.security.handler.OidcAuthenticationToken) HttpServletResponse(javax.servlet.http.HttpServletResponse) JEESessionStore(org.pac4j.core.context.session.JEESessionStore) HandlerResult(org.codice.ddf.security.handler.api.HandlerResult) HttpServletRequest(javax.servlet.http.HttpServletRequest) OidcConfiguration(org.pac4j.oidc.config.OidcConfiguration) OidcCredentials(org.pac4j.oidc.credentials.OidcCredentials)

Example 2 with HandlerResultImpl

use of org.codice.ddf.security.handler.HandlerResultImpl in project ddf by codice.

the class WebSSOFilter method handleRequest.

private void handleRequest(HttpServletRequest httpRequest, HttpServletResponse httpResponse, SecurityFilterChain filterChain, List<AuthenticationHandler> handlers) throws AuthenticationException, IOException {
    HandlerResult result = null;
    // First pass, see if anyone can come up with proper security token from the get-go
    LOGGER.debug("Checking for existing tokens in request.");
    final String path = httpRequest.getRequestURI();
    String ipAddress = httpRequest.getHeader("X-FORWARDED-FOR");
    if (ipAddress == null) {
        ipAddress = httpRequest.getRemoteAddr();
    }
    if (contextPolicyManager.getSessionAccess()) {
        result = checkForPreviousResultOnSession(httpRequest, ipAddress);
    }
    // no result found on session, try and get result from handlers
    if (result == null) {
        if (!handlers.isEmpty()) {
            result = getResultFromHandlers(httpRequest, httpResponse, filterChain, handlers);
        } else {
            // no configured handlers
            if (contextPolicyManager.getGuestAccess()) {
                LOGGER.trace("No configured handlers found, but guest access is enabled. Continuing with an empty handler result for guest login.");
                result = new HandlerResultImpl(Status.NO_ACTION, null);
                result.setSource("default");
            } else {
                LOGGER.warn("No configured handler found and guest access is disabled. Returning status code 503, Service Unavailable. Check system configuration and bundle state.");
                returnSimpleResponse(HttpServletResponse.SC_SERVICE_UNAVAILABLE, httpResponse);
                return;
            }
        }
    }
    handleResultStatus(httpRequest, httpResponse, result, path, ipAddress);
    // If we got here, we've received our tokens to continue
    LOGGER.debug("Invoking the rest of the filter chain");
    try {
        filterChain.doFilter(httpRequest, httpResponse);
    } catch (Exception e) {
        LOGGER.debug("Exception in filter chain - passing off to handlers. Msg: {}", e.getMessage(), e);
        // First pass, see if anyone can come up with proper security token
        // from the git-go
        result = null;
        for (AuthenticationHandler auth : handlers) {
            result = auth.handleError(httpRequest, httpResponse, filterChain);
            if (result.getStatus() != HandlerResult.Status.NO_ACTION) {
                LOGGER.debug("Handler {} set the status to {}", auth.getAuthenticationType(), result.getStatus());
                break;
            }
        }
        if (result == null || result.getStatus() == HandlerResult.Status.NO_ACTION) {
            LOGGER.debug("Error during authentication - no error recovery attempted - returning bad request.");
            httpResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST);
            httpResponse.flushBuffer();
        }
        throw new AuthenticationFailureException(e);
    }
}
Also used : HandlerResultImpl(org.codice.ddf.security.handler.HandlerResultImpl) HandlerResult(org.codice.ddf.security.handler.api.HandlerResult) AuthenticationHandler(org.codice.ddf.security.handler.api.AuthenticationHandler) AuthenticationFailureException(org.codice.ddf.platform.filter.AuthenticationFailureException) AuthenticationChallengeException(org.codice.ddf.platform.filter.AuthenticationChallengeException) AuthenticationFailureException(org.codice.ddf.platform.filter.AuthenticationFailureException) SessionException(org.apache.shiro.session.SessionException) IOException(java.io.IOException) AuthenticationException(org.codice.ddf.platform.filter.AuthenticationException)

Example 3 with HandlerResultImpl

use of org.codice.ddf.security.handler.HandlerResultImpl in project ddf by codice.

the class WebSSOFilter method checkForPreviousResultOnSession.

private HandlerResult checkForPreviousResultOnSession(HttpServletRequest httpRequest, String ip) {
    String requestedSessionId = httpRequest.getRequestedSessionId();
    if (requestedSessionId == null) {
        LOGGER.trace("No HTTP Session - returning with no results");
        return null;
    }
    HttpSession session = httpRequest.getSession(false);
    if (session == null) {
        // has not yet been created for them.
        if (sessionFactory == null) {
            throw new SessionException("Unable to verify user's session.");
        }
        session = sessionFactory.getOrCreateSession(httpRequest);
    }
    // See if principals exist for the requested session id
    HandlerResult result = null;
    PrincipalHolder principalHolder = (PrincipalHolder) session.getAttribute(SecurityConstants.SECURITY_TOKEN_KEY);
    if (principalHolder != null && principalHolder.getPrincipals() != null) {
        Collection<SecurityAssertion> assertions = principalHolder.getPrincipals().byType(SecurityAssertion.class);
        SessionToken sessionToken = null;
        if (!assertions.isEmpty()) {
            sessionToken = new SessionToken(principalHolder.getPrincipals(), session.getId(), ip);
        }
        if (sessionToken != null) {
            result = new HandlerResultImpl();
            result.setToken(sessionToken);
            result.setStatus(HandlerResult.Status.COMPLETED);
        } else {
            principalHolder.remove();
        }
    } else {
        securityLogger.audit("Request contained invalid or expired session id [{}]", Hashing.sha256().hashString(requestedSessionId, StandardCharsets.UTF_8).toString());
        LOGGER.trace("Request contained invalid or expired session - returning with no results");
    }
    return result;
}
Also used : SessionToken(org.codice.ddf.security.handler.SessionToken) HttpSession(javax.servlet.http.HttpSession) HandlerResultImpl(org.codice.ddf.security.handler.HandlerResultImpl) SessionException(org.apache.shiro.session.SessionException) HandlerResult(org.codice.ddf.security.handler.api.HandlerResult) SecurityAssertion(ddf.security.assertion.SecurityAssertion) PrincipalHolder(ddf.security.common.PrincipalHolder)

Example 4 with HandlerResultImpl

use of org.codice.ddf.security.handler.HandlerResultImpl in project ddf by codice.

the class WebSSOFilter method handleResultStatus.

private void handleResultStatus(HttpServletRequest httpRequest, HttpServletResponse httpResponse, HandlerResult result, String path, String ipAddress) throws AuthenticationChallengeException, AuthenticationFailureException {
    if (result != null) {
        switch(result.getStatus()) {
            case REDIRECTED:
                // handler handled the response - it is redirecting or whatever
                // necessary to get their tokens
                LOGGER.debug("Stopping filter chain - handled by plugins");
                throw new AuthenticationChallengeException("Stopping filter chain - handled by plugins");
            case NO_ACTION:
                if (!contextPolicyManager.getGuestAccess()) {
                    LOGGER.warn("No handlers were able to determine required credentials, returning bad request to {}. Check policy configuration for path: {}", ipAddress, path);
                    returnSimpleResponse(HttpServletResponse.SC_BAD_REQUEST, httpResponse);
                    throw new AuthenticationFailureException("No handlers were able to determine required credentials");
                }
                result = new HandlerResultImpl(Status.COMPLETED, new GuestAuthenticationToken(ipAddress, securityLogger));
                result.setSource("default");
            // fall through
            case COMPLETED:
                if (result.getToken() == null) {
                    LOGGER.warn("Completed without credentials for {} - check context policy configuration for path: {}", ipAddress, path);
                    returnSimpleResponse(HttpServletResponse.SC_BAD_REQUEST, httpResponse);
                    throw new AuthenticationFailureException("Completed without credentials");
                }
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug("Attaching result handler to the http request - token is instance of {} from classloader {}", result.getToken().getClass().getName(), result.getToken().getClass().getClassLoader());
                }
                if (result.getToken() instanceof BaseAuthenticationToken) {
                    ((BaseAuthenticationToken) result.getToken()).setAllowGuest(contextPolicyManager.getGuestAccess());
                }
                httpRequest.setAttribute(AUTHENTICATION_TOKEN_KEY, result);
                break;
            default:
                LOGGER.warn("Unexpected response from handler - ignoring. Remote IP: {}, Path: {}", ipAddress, path);
                throw new AuthenticationFailureException("Unexpected response from handler");
        }
    } else {
        LOGGER.warn("Expected login credentials from {} - didn't find any. Returning a bad request for path: {}", ipAddress, path);
        returnSimpleResponse(HttpServletResponse.SC_BAD_REQUEST, httpResponse);
        throw new AuthenticationFailureException("Didn't find any login credentials");
    }
}
Also used : AuthenticationChallengeException(org.codice.ddf.platform.filter.AuthenticationChallengeException) GuestAuthenticationToken(org.codice.ddf.security.handler.GuestAuthenticationToken) HandlerResultImpl(org.codice.ddf.security.handler.HandlerResultImpl) BaseAuthenticationToken(org.codice.ddf.security.handler.BaseAuthenticationToken) AuthenticationFailureException(org.codice.ddf.platform.filter.AuthenticationFailureException)

Example 5 with HandlerResultImpl

use of org.codice.ddf.security.handler.HandlerResultImpl in project ddf by codice.

the class PKIHandler method handleError.

@Override
public HandlerResult handleError(ServletRequest servletRequest, ServletResponse servletResponse, SecurityFilterChain chain) {
    HandlerResult result = new HandlerResultImpl(HandlerResult.Status.NO_ACTION, null);
    result.setSource(SOURCE);
    LOGGER.debug("In error handler for pki - no action taken.");
    return result;
}
Also used : HandlerResultImpl(org.codice.ddf.security.handler.HandlerResultImpl) HandlerResult(org.codice.ddf.security.handler.api.HandlerResult)

Aggregations

HandlerResultImpl (org.codice.ddf.security.handler.HandlerResultImpl)18 HandlerResult (org.codice.ddf.security.handler.api.HandlerResult)17 HttpServletRequest (javax.servlet.http.HttpServletRequest)7 IOException (java.io.IOException)5 HttpServletResponse (javax.servlet.http.HttpServletResponse)5 AuthenticationFailureException (org.codice.ddf.platform.filter.AuthenticationFailureException)4 Test (org.junit.Test)4 SecurityAssertionSaml (ddf.security.assertion.saml.impl.SecurityAssertionSaml)2 PrincipalHolder (ddf.security.common.PrincipalHolder)2 Cookie (javax.servlet.http.Cookie)2 AuthenticationToken (org.apache.shiro.authc.AuthenticationToken)2 SessionException (org.apache.shiro.session.SessionException)2 SimplePrincipalCollection (org.apache.shiro.subject.SimplePrincipalCollection)2 AuthenticationChallengeException (org.codice.ddf.platform.filter.AuthenticationChallengeException)2 AuthenticationException (org.codice.ddf.platform.filter.AuthenticationException)2 BaseAuthenticationToken (org.codice.ddf.security.handler.BaseAuthenticationToken)2 OidcAuthenticationToken (org.codice.ddf.security.handler.OidcAuthenticationToken)2 SAMLAuthenticationToken (org.codice.ddf.security.handler.SAMLAuthenticationToken)2 JEEContext (org.pac4j.core.context.JEEContext)2 JEESessionStore (org.pac4j.core.context.session.JEESessionStore)2