Search in sources :

Example 1 with OidcAuthenticationToken

use of org.codice.ddf.security.handler.OidcAuthenticationToken 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 OidcAuthenticationToken

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

the class OidcRealm method doGetAuthenticationInfo.

@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
    // token is guaranteed to be of type OidcAuthenticationToken by the supports() method
    OidcAuthenticationToken oidcAuthenticationToken = (OidcAuthenticationToken) authenticationToken;
    OidcCredentials credentials = (OidcCredentials) oidcAuthenticationToken.getCredentials();
    OidcConfiguration oidcConfiguration = oidcHandlerConfiguration.getOidcConfiguration();
    OIDCProviderMetadata oidcProviderMetadata = oidcConfiguration.findProviderMetadata();
    WebContext webContext = (WebContext) oidcAuthenticationToken.getContext();
    OidcClient<OidcConfiguration> oidcClient = oidcHandlerConfiguration.getOidcClient(webContext.getFullRequestURL());
    int connectTimeout = oidcHandlerConfiguration.getConnectTimeout();
    int readTimeout = oidcHandlerConfiguration.getReadTimeout();
    try {
        OidcCredentialsResolver oidcCredentialsResolver = new OidcCredentialsResolver(oidcConfiguration, oidcClient, oidcProviderMetadata, connectTimeout, readTimeout);
        oidcCredentialsResolver.resolveIdToken(credentials, webContext);
    } catch (TechnicalException e) {
        throw new AuthenticationException(e);
    }
    // problem getting id token, invalidate credentials
    if (credentials.getIdToken() == null) {
        webContext.getSessionStore().destroySession(webContext);
        String msg = String.format("Could not fetch id token with Oidc credentials (%s). " + "This may be due to the credentials expiring. " + "Invalidating session in order to acquire valid credentials.", credentials);
        LOGGER.warn(msg);
        throw new AuthenticationException(msg);
    }
    OidcProfileCreator oidcProfileCreator = new CustomOidcProfileCreator(oidcConfiguration, oidcClient);
    Optional<UserProfile> userProfile = oidcProfileCreator.create(credentials, webContext);
    SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo();
    simpleAuthenticationInfo.setCredentials(credentials);
    if (userProfile.isPresent()) {
        OidcProfile oidcProfile = (OidcProfile) userProfile.get();
        simpleAuthenticationInfo.setPrincipals(createPrincipalCollectionFromCredentials(oidcProfile));
    } else {
        simpleAuthenticationInfo.setPrincipals(new SimplePrincipalCollection());
    }
    return simpleAuthenticationInfo;
}
Also used : WebContext(org.pac4j.core.context.WebContext) TechnicalException(org.pac4j.core.exception.TechnicalException) UserProfile(org.pac4j.core.profile.UserProfile) SimpleAuthenticationInfo(org.apache.shiro.authc.SimpleAuthenticationInfo) AuthenticationException(org.apache.shiro.authc.AuthenticationException) OidcAuthenticationToken(org.codice.ddf.security.handler.OidcAuthenticationToken) SimplePrincipalCollection(org.apache.shiro.subject.SimplePrincipalCollection) OidcCredentialsResolver(org.codice.ddf.security.oidc.resolver.OidcCredentialsResolver) OidcConfiguration(org.pac4j.oidc.config.OidcConfiguration) OidcCredentials(org.pac4j.oidc.credentials.OidcCredentials) OidcProfileCreator(org.pac4j.oidc.profile.creator.OidcProfileCreator) OidcProfile(org.pac4j.oidc.profile.OidcProfile) OIDCProviderMetadata(com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata)

Example 3 with OidcAuthenticationToken

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

the class OidcRealm method supports.

/**
 * Determine if the supplied token is supported by this realm.
 */
@Override
public boolean supports(AuthenticationToken token) {
    if (!(token instanceof OidcAuthenticationToken)) {
        LOGGER.debug("The supplied authentication token is not an instance of SessionToken or OidcAuthenticationToken. Sending back not supported.");
        return false;
    }
    OidcAuthenticationToken oidcToken = (OidcAuthenticationToken) token;
    OidcCredentials credentials = (OidcCredentials) oidcToken.getCredentials();
    if (credentials == null || (credentials.getCode() == null && credentials.getAccessToken() == null && credentials.getIdToken() == null)) {
        LOGGER.debug("The supplied authentication token has null/empty credentials. Sending back no supported.");
        return false;
    }
    WebContext webContext = (WebContext) oidcToken.getContext();
    if (webContext == null) {
        LOGGER.debug("The supplied authentication token has null web context. Sending back not supported.");
        return false;
    }
    LOGGER.debug("Token {} is supported by {}.", token.getClass(), OidcRealm.class.getName());
    return true;
}
Also used : OidcCredentials(org.pac4j.oidc.credentials.OidcCredentials) WebContext(org.pac4j.core.context.WebContext) OidcAuthenticationToken(org.codice.ddf.security.handler.OidcAuthenticationToken)

Example 4 with OidcAuthenticationToken

use of org.codice.ddf.security.handler.OidcAuthenticationToken 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)

Aggregations

OidcAuthenticationToken (org.codice.ddf.security.handler.OidcAuthenticationToken)4 OidcCredentials (org.pac4j.oidc.credentials.OidcCredentials)4 HttpServletRequest (javax.servlet.http.HttpServletRequest)2 HttpServletResponse (javax.servlet.http.HttpServletResponse)2 HandlerResultImpl (org.codice.ddf.security.handler.HandlerResultImpl)2 HandlerResult (org.codice.ddf.security.handler.api.HandlerResult)2 JEEContext (org.pac4j.core.context.JEEContext)2 WebContext (org.pac4j.core.context.WebContext)2 JEESessionStore (org.pac4j.core.context.session.JEESessionStore)2 TechnicalException (org.pac4j.core.exception.TechnicalException)2 OidcConfiguration (org.pac4j.oidc.config.OidcConfiguration)2 OIDCProviderMetadata (com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata)1 AuthenticationException (org.apache.shiro.authc.AuthenticationException)1 SimpleAuthenticationInfo (org.apache.shiro.authc.SimpleAuthenticationInfo)1 SimplePrincipalCollection (org.apache.shiro.subject.SimplePrincipalCollection)1 OidcCredentialsResolver (org.codice.ddf.security.oidc.resolver.OidcCredentialsResolver)1 UserProfile (org.pac4j.core.profile.UserProfile)1 OAuthCredentialsException (org.pac4j.oauth.exception.OAuthCredentialsException)1 OidcProfile (org.pac4j.oidc.profile.OidcProfile)1 OidcProfileCreator (org.pac4j.oidc.profile.creator.OidcProfileCreator)1