Search in sources :

Example 1 with JEESessionStore

use of org.pac4j.core.context.session.JEESessionStore in project ddf by codice.

the class OidcCallbackEndpoint method logout.

@GET
@Path("/logout")
public Response logout(@Context HttpServletRequest request, @Context HttpServletResponse response) {
    if (request == null) {
        throw new IllegalArgumentException("Passed in request cannot be null.");
    }
    if (response == null) {
        throw new IllegalArgumentException("Passed in response cannot be null.");
    }
    if (request.getSession(false) == null) {
        throw new IllegalArgumentException("Passed in request must have a corresponding session to logout.");
    }
    JEESessionStore sessionStore = new JEESessionStore();
    JEEContext jeeContext = new JEEContext(request, response, sessionStore);
    this.securityLogger.audit("Logging out");
    sessionStore.destroySession(jeeContext);
    String localLogout = SystemBaseUrl.EXTERNAL.constructUrl("/logout/local");
    WebClient webClient = getWebClient(localLogout);
    Response logoutResponse = webClient.get();
    if (logoutResponse.getStatus() == HttpStatus.SC_INTERNAL_SERVER_ERROR) {
        return logoutResponse;
    }
    try {
        String redirectUrl = SystemBaseUrl.EXTERNAL.constructUrl(redirectUri, false);
        URIBuilder redirectUrlBuilder = new URIBuilder(redirectUrl);
        String prevUrl = request.getParameter("prevurl");
        if (prevUrl != null) {
            redirectUrlBuilder.addParameter("prevurl", prevUrl);
        }
        return Response.seeOther(redirectUrlBuilder.build()).build();
    } catch (URISyntaxException e) {
        LOGGER.debug("Unable to create logout response URL for OIDC logout.", e);
    }
    return Response.serverError().build();
}
Also used : HttpServletResponse(javax.servlet.http.HttpServletResponse) Response(javax.ws.rs.core.Response) JEEContext(org.pac4j.core.context.JEEContext) JEESessionStore(org.pac4j.core.context.session.JEESessionStore) URISyntaxException(java.net.URISyntaxException) WebClient(org.apache.cxf.jaxrs.client.WebClient) URIBuilder(org.apache.http.client.utils.URIBuilder) Path(javax.ws.rs.Path) GET(javax.ws.rs.GET)

Example 2 with JEESessionStore

use of org.pac4j.core.context.session.JEESessionStore 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 3 with JEESessionStore

use of org.pac4j.core.context.session.JEESessionStore in project knox by apache.

the class Pac4jDispatcherFilter method init.

@Override
public void init(FilterConfig filterConfig) throws ServletException {
    // JWT service
    final ServletContext context = filterConfig.getServletContext();
    CryptoService cryptoService = null;
    String clusterName = null;
    if (context != null) {
        GatewayServices services = (GatewayServices) context.getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
        clusterName = (String) context.getAttribute(GatewayServices.GATEWAY_CLUSTER_ATTRIBUTE);
        if (services != null) {
            keystoreService = services.getService(ServiceType.KEYSTORE_SERVICE);
            cryptoService = services.getService(ServiceType.CRYPTO_SERVICE);
            aliasService = services.getService(ServiceType.ALIAS_SERVICE);
            masterService = services.getService(ServiceType.MASTER_SERVICE);
        }
    }
    // crypto service, alias service and cluster name are mandatory
    if (cryptoService == null || aliasService == null || clusterName == null) {
        log.cryptoServiceAndAliasServiceAndClusterNameRequired();
        throw new ServletException("The crypto service, alias service and cluster name are required.");
    }
    try {
        aliasService.getPasswordFromAliasForCluster(clusterName, KnoxSessionStore.PAC4J_PASSWORD, true);
    } catch (AliasServiceException e) {
        log.unableToGenerateAPasswordForEncryption(e);
        throw new ServletException("Unable to generate a password for encryption.");
    }
    // url to SSO authentication provider
    String pac4jCallbackUrl = filterConfig.getInitParameter(PAC4J_CALLBACK_URL);
    if (pac4jCallbackUrl == null) {
        log.ssoAuthenticationProviderUrlRequired();
        throw new ServletException("Required pac4j callback URL is missing.");
    }
    // client name from servlet parameter (mandatory)
    final String clientNameParameter = filterConfig.getInitParameter(PAC4J_CLIENT_NAME_PARAM);
    if (clientNameParameter == null) {
        log.clientNameParameterRequired();
        throw new ServletException("Required pac4j clientName parameter is missing.");
    }
    final String oidcType = filterConfig.getInitParameter(PAC4J_OIDC_TYPE);
    /*
       add the callback parameter to know it's a callback,
       Azure AD does not honor query param so we add callback param as path element.
    */
    if (AzureAdClient.class.getSimpleName().equals(clientNameParameter) || (!StringUtils.isBlank(oidcType) && PAC4J_OICD_TYPE_AZURE.equals(oidcType))) {
        pac4jCallbackUrl = pac4jCallbackUrl + URL_PATH_SEPARATOR + PAC4J_CALLBACK_PARAMETER;
    } else {
        pac4jCallbackUrl = CommonHelper.addParameter(pac4jCallbackUrl, PAC4J_CALLBACK_PARAMETER, "true");
    }
    final Config config;
    final String clientName;
    if (TEST_BASIC_AUTH.equalsIgnoreCase(clientNameParameter)) {
        // test configuration
        final IndirectBasicAuthClient indirectBasicAuthClient = new IndirectBasicAuthClient(new SimpleTestUsernamePasswordAuthenticator());
        indirectBasicAuthClient.setRealmName("Knox TEST");
        config = new Config(pac4jCallbackUrl, indirectBasicAuthClient);
        clientName = "IndirectBasicAuthClient";
    } else {
        // get clients from the init parameters
        final Map<String, String> properties = new HashMap<>();
        final Enumeration<String> names = filterConfig.getInitParameterNames();
        addDefaultConfig(clientNameParameter, properties);
        while (names.hasMoreElements()) {
            final String key = names.nextElement();
            properties.put(key, resolveAlias(clusterName, key, filterConfig.getInitParameter(key)));
        }
        final PropertiesConfigFactory propertiesConfigFactory = new PropertiesConfigFactory(pac4jCallbackUrl, properties);
        config = propertiesConfigFactory.build();
        final List<Client> clients = config.getClients().getClients();
        if (clients == null || clients.isEmpty()) {
            log.atLeastOnePac4jClientMustBeDefined();
            throw new ServletException("At least one pac4j client must be defined.");
        }
        clientName = CommonHelper.isBlank(clientNameParameter) ? clients.get(0).getName() : clientNameParameter;
        /* do we need to exclude groups? */
        setSessionStoreConfig(filterConfig, PAC4J_SESSION_STORE_EXCLUDE_GROUPS, PAC4J_SESSION_STORE_EXCLUDE_GROUPS_DEFAULT);
        /* do we need to exclude roles? */
        setSessionStoreConfig(filterConfig, PAC4J_SESSION_STORE_EXCLUDE_ROLES, PAC4J_SESSION_STORE_EXCLUDE_ROLES_DEFAULT);
        /* do we need to exclude permissions? */
        setSessionStoreConfig(filterConfig, PAC4J_SESSION_STORE_EXCLUDE_PERMISSIONS, PAC4J_SESSION_STORE_EXCLUDE_PERMISSIONS_DEFAULT);
        /* do we need to exclude custom attributes? */
        setSessionStoreConfig(filterConfig, PAC4J_SESSION_STORE_EXCLUDE_CUSTOM_ATTRIBUTES, PAC4J_SESSION_STORE_EXCLUDE_CUSTOM_ATTRIBUTES_DEFAULT);
        // decorating client configuration (if needed)
        PAC4J_CLIENT_CONFIGURATION_DECORATOR.decorateClients(clients, properties);
    }
    callbackFilter = new CallbackFilter();
    callbackFilter.init(filterConfig);
    callbackFilter.setConfigOnly(config);
    securityFilter = new SecurityFilter();
    securityFilter.setClients(clientName);
    securityFilter.setConfigOnly(config);
    final String domainSuffix = filterConfig.getInitParameter(PAC4J_COOKIE_DOMAIN_SUFFIX_PARAM);
    final String sessionStoreVar = filterConfig.getInitParameter(PAC4J_SESSION_STORE);
    SessionStore sessionStore;
    if (!StringUtils.isBlank(sessionStoreVar) && JEESessionStore.class.getName().contains(sessionStoreVar)) {
        sessionStore = new JEESessionStore();
    } else {
        sessionStore = new KnoxSessionStore(cryptoService, clusterName, domainSuffix, sessionStoreConfigs);
    }
    config.setSessionStore(sessionStore);
}
Also used : GatewayServices(org.apache.knox.gateway.services.GatewayServices) KnoxSessionStore(org.apache.knox.gateway.pac4j.session.KnoxSessionStore) HashMap(java.util.HashMap) FilterConfig(javax.servlet.FilterConfig) Config(org.pac4j.core.config.Config) AliasServiceException(org.apache.knox.gateway.services.security.AliasServiceException) JEESessionStore(org.pac4j.core.context.session.JEESessionStore) ServletException(javax.servlet.ServletException) KnoxSessionStore(org.apache.knox.gateway.pac4j.session.KnoxSessionStore) SessionStore(org.pac4j.core.context.session.SessionStore) JEESessionStore(org.pac4j.core.context.session.JEESessionStore) CryptoService(org.apache.knox.gateway.services.security.CryptoService) PropertiesConfigFactory(org.pac4j.config.client.PropertiesConfigFactory) SecurityFilter(org.pac4j.jee.filter.SecurityFilter) ServletContext(javax.servlet.ServletContext) CallbackFilter(org.pac4j.jee.filter.CallbackFilter) AzureAdClient(org.pac4j.oidc.client.AzureAdClient) SAML2Client(org.pac4j.saml.client.SAML2Client) Client(org.pac4j.core.client.Client) IndirectBasicAuthClient(org.pac4j.http.client.indirect.IndirectBasicAuthClient) IndirectBasicAuthClient(org.pac4j.http.client.indirect.IndirectBasicAuthClient) SimpleTestUsernamePasswordAuthenticator(org.pac4j.http.credentials.authenticator.test.SimpleTestUsernamePasswordAuthenticator)

Example 4 with JEESessionStore

use of org.pac4j.core.context.session.JEESessionStore in project ddf by codice.

the class OAuthHandler method getNormalizedToken.

@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);
    }
    JEESessionStore sessionStore = new JEESessionStore();
    JEEContext jeeContext = new JEEContext(httpRequest, httpResponse, sessionStore);
    // time to try and pull credentials off of the request
    LOGGER.debug("Doing OAuth authentication and authorization for path {}.", httpRequest.getContextPath());
    OidcCredentials credentials;
    StringBuffer requestUrlBuffer = httpRequest.getRequestURL();
    requestUrlBuffer.append(httpRequest.getQueryString() == null ? "" : "?" + httpRequest.getQueryString());
    String ipAddress = httpRequest.getRemoteAddr();
    boolean isMachine = userAgentIsNotBrowser(httpRequest);
    // machine to machine, check for Client Credentials Flow credentials
    if (isMachine) {
        try {
            credentials = getCredentialsFromRequest(jeeContext);
        } catch (IllegalArgumentException e) {
            LOGGER.error("Problem with the OAuth Handler's OAuthHandlerConfiguration. " + "Check the OAuth Handler Configuration in the admin console.", e);
            return noActionResult;
        } catch (OAuthCredentialsException e) {
            LOGGER.error("Problem extracting credentials from machine to machine request. " + "See OAuth2's \"Client Credential Flow\" for more information.", e);
            return noActionResult;
        }
    } else {
        LOGGER.info("The OAuth Handler does not handle user agent requests. Continuing to other handlers.");
        return noActionResult;
    }
    // if the request has credentials, process it
    if (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 {
        LOGGER.info("No credentials found on user-agent request. " + "This handler does not support the acquisition of user agent credentials. Continuing to other handlers.");
        return noActionResult;
    }
}
Also used : 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) OidcCredentials(org.pac4j.oidc.credentials.OidcCredentials) OAuthCredentialsException(org.pac4j.oauth.exception.OAuthCredentialsException)

Example 5 with JEESessionStore

use of org.pac4j.core.context.session.JEESessionStore in project ddf by codice.

the class OidcLogoutActionProvider method getAction.

/**
 * *
 *
 * @param <T> is a Map<String, Subject>
 * @param subjectMap containing the corresponding subject
 * @return OidcLogoutActionProvider containing the logout url
 */
@Override
public <T> Action getAction(T subjectMap) {
    if (!canHandle(subjectMap)) {
        return null;
    }
    String logoutUrlString = "";
    URL logoutUrl = null;
    try {
        HttpServletRequest request = (HttpServletRequest) ((Map) subjectMap).get("http_request");
        HttpServletResponse response = (HttpServletResponse) ((Map) subjectMap).get("http_response");
        JEESessionStore sessionStore = new JEESessionStore();
        JEEContext jeeContext = new JEEContext(request, response, sessionStore);
        HttpSession session = request.getSession(false);
        PrincipalHolder principalHolder = null;
        if (session != null) {
            principalHolder = (PrincipalHolder) session.getAttribute(SecurityConstants.SECURITY_TOKEN_KEY);
        }
        OidcProfile oidcProfile = null;
        if (principalHolder != null && principalHolder.getPrincipals() != null) {
            Collection<SecurityAssertion> securityAssertions = principalHolder.getPrincipals().byType(SecurityAssertion.class);
            for (SecurityAssertion securityAssertion : securityAssertions) {
                if (SecurityAssertionJwt.JWT_TOKEN_TYPE.equals(securityAssertion.getTokenType())) {
                    oidcProfile = (OidcProfile) securityAssertion.getToken();
                    break;
                }
            }
        }
        if (oidcProfile == null) {
            throw new IllegalStateException("Unable to determine OIDC profile for logout");
        }
        OidcLogoutActionBuilder logoutActionBuilder = handlerConfiguration.getOidcLogoutActionBuilder();
        logoutActionBuilder.setAjaxRequestResolver(new DefaultAjaxRequestResolver() {

            @Override
            public boolean isAjax(final WebContext context) {
                return false;
            }
        });
        URIBuilder urlBuilder = new URIBuilder(SystemBaseUrl.EXTERNAL.constructUrl("/oidc/logout", true));
        String prevUrl = getPreviousUrl(request);
        if (prevUrl != null) {
            urlBuilder.addParameter(PREV_URL, prevUrl);
        }
        RedirectionAction logoutAction = logoutActionBuilder.getLogoutAction(jeeContext, oidcProfile, urlBuilder.build().toString()).orElse(null);
        if (logoutAction instanceof WithLocationAction) {
            logoutUrlString = ((WithLocationAction) logoutAction).getLocation();
        }
        logoutUrl = new URL(logoutUrlString);
    } catch (MalformedURLException | URISyntaxException e) {
        LOGGER.info("Unable to resolve logout URL: {}", logoutUrlString);
    } catch (ClassCastException e) {
        LOGGER.debug("Unable to cast parameter to Map<String, Object>, {}", subjectMap, e);
    }
    return new ActionImpl(ID, TITLE, DESCRIPTION, logoutUrl);
}
Also used : RedirectionAction(org.pac4j.core.exception.http.RedirectionAction) MalformedURLException(java.net.MalformedURLException) WebContext(org.pac4j.core.context.WebContext) HttpSession(javax.servlet.http.HttpSession) JEEContext(org.pac4j.core.context.JEEContext) HttpServletResponse(javax.servlet.http.HttpServletResponse) JEESessionStore(org.pac4j.core.context.session.JEESessionStore) WithLocationAction(org.pac4j.core.exception.http.WithLocationAction) URISyntaxException(java.net.URISyntaxException) SecurityAssertion(ddf.security.assertion.SecurityAssertion) URL(java.net.URL) URIBuilder(org.apache.http.client.utils.URIBuilder) HttpServletRequest(javax.servlet.http.HttpServletRequest) DefaultAjaxRequestResolver(org.pac4j.core.http.ajax.DefaultAjaxRequestResolver) OidcLogoutActionBuilder(org.pac4j.oidc.logout.OidcLogoutActionBuilder) ActionImpl(ddf.action.impl.ActionImpl) OidcProfile(org.pac4j.oidc.profile.OidcProfile) PrincipalHolder(ddf.security.common.PrincipalHolder)

Aggregations

JEESessionStore (org.pac4j.core.context.session.JEESessionStore)5 HttpServletResponse (javax.servlet.http.HttpServletResponse)4 JEEContext (org.pac4j.core.context.JEEContext)4 HttpServletRequest (javax.servlet.http.HttpServletRequest)3 URISyntaxException (java.net.URISyntaxException)2 URIBuilder (org.apache.http.client.utils.URIBuilder)2 HandlerResultImpl (org.codice.ddf.security.handler.HandlerResultImpl)2 OidcAuthenticationToken (org.codice.ddf.security.handler.OidcAuthenticationToken)2 HandlerResult (org.codice.ddf.security.handler.api.HandlerResult)2 OidcCredentials (org.pac4j.oidc.credentials.OidcCredentials)2 ActionImpl (ddf.action.impl.ActionImpl)1 SecurityAssertion (ddf.security.assertion.SecurityAssertion)1 PrincipalHolder (ddf.security.common.PrincipalHolder)1 MalformedURLException (java.net.MalformedURLException)1 URL (java.net.URL)1 HashMap (java.util.HashMap)1 FilterConfig (javax.servlet.FilterConfig)1 ServletContext (javax.servlet.ServletContext)1 ServletException (javax.servlet.ServletException)1 HttpSession (javax.servlet.http.HttpSession)1