All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.brightsparklabs.dropwizard.bundles.auth.external.HeaderFieldsAuthenticator Maven / Gradle / Ivy

The newest version!
/*
 * Maintained by brightSPARK Labs.
 * www.brightsparklabs.com
 *
 * Refer to LICENSE at repository root for license details.
 */

package com.brightsparklabs.dropwizard.bundles.auth.external;

import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import jakarta.ws.rs.core.MultivaluedMap;
import java.security.Principal;
import java.util.Optional;
import java.util.stream.StreamSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Determines if a user is authenticated based on the presence/values in various header fields. This
 * should only be used behind a reverse proxy where the proxy inserts appropriate 'internal' header
 * fields (and strips out any fields the end user provides in the request). Authenticator} for it to
 * determine if the user should be considered authenticated.
 *
 * @param 

Type of {@link Principal} to return for authenticated users. * @author brightSPARK Labs */ public class HeaderFieldsAuthenticator

extends ExternalAuthenticator, P> { // ------------------------------------------------------------------------- // CONSTANTS // ------------------------------------------------------------------------- /** Default field to use to extract the username */ private static final String DEFAULT_FIELD_USERNAME = "X-Auth-Username"; /** Default field to use to extract the firstname */ private static final String DEFAULT_FIELD_FIRSTNAME = "X-Auth-Given-Name"; /** Default field to use to extract the lastname */ private static final String DEFAULT_FIELD_LASTNAME = "X-Auth-Family-Name"; /** Default field to use to extract the email */ private static final String DEFAULT_FIELD_EMAIL = "X-Auth-Email"; /** Default field to use to extract the groups */ private static final String DEFAULT_FIELD_GROUPS = "X-Auth-Groups"; /** Default field to use to extract the roles */ private static final String DEFAULT_FIELD_ROLES = "X-Auth-Roles"; // ------------------------------------------------------------------------- // CLASS VARIABLES // ------------------------------------------------------------------------- /** Class logger */ private static Logger logger = LoggerFactory.getLogger(HeaderFieldsAuthFilter.class); /** Splits comma separated strings */ private static final Splitter splitOnCommas = Splitter.on(',').omitEmptyStrings().trimResults(); // ------------------------------------------------------------------------- // INSTANCE VARIABLES // ------------------------------------------------------------------------- // ------------------------------------------------------------------------- // CONSTRUCTION // ------------------------------------------------------------------------- /** * Default constructor. * * @param principalConverter Converter between {@link InternalUser} and the {@link Principal} * used in the system. * @param listeners The authentication event listeners */ public HeaderFieldsAuthenticator( final PrincipalConverter

principalConverter, final Iterable listeners) { super(principalConverter, listeners); } // ------------------------------------------------------------------------- // IMPLEMENTATION: ExternalAuthenticator // ------------------------------------------------------------------------- @Override public InternalUser doAuthenticate(final MultivaluedMap headers) throws AuthenticationDeniedException { logger.info("Authenticating via header fields ..."); if (headers == null) { throw new AuthenticationDeniedException("No header fields provided to authenticator"); } // extract groups and roles final ImmutableList groups = headers.getOrDefault(DEFAULT_FIELD_GROUPS, ImmutableList.of()).stream() .map(splitOnCommas::split) .flatMap(x -> StreamSupport.stream(x.spliterator(), false)) .collect(ImmutableList.toImmutableList()); final ImmutableList roles = headers.getOrDefault(DEFAULT_FIELD_ROLES, ImmutableList.of()).stream() .map(splitOnCommas::split) .flatMap(x -> StreamSupport.stream(x.spliterator(), false)) .collect(ImmutableList.toImmutableList()); final String username = headers.getFirst(DEFAULT_FIELD_USERNAME); try { final ImmutableInternalUser user = ImmutableInternalUser.builder() .username(extractHeaderValue(DEFAULT_FIELD_USERNAME, headers)) .firstname(extractHeaderValue(DEFAULT_FIELD_FIRSTNAME, headers)) .lastname(extractHeaderValue(DEFAULT_FIELD_LASTNAME, headers)) .email(Optional.ofNullable(headers.getFirst(DEFAULT_FIELD_EMAIL))) .groups(groups) .roles(roles) .build(); logger.info("Authentication successful for username [{}]", username); return user; } catch (IllegalArgumentException ex) { final String errorMessage = String.format( "Authentication denied for username [%s] - %s", username, ex.getMessage()); logger.info(errorMessage); throw new AuthenticationDeniedException(errorMessage); } } // ------------------------------------------------------------------------- // PUBLIC METHODS // ------------------------------------------------------------------------- // ------------------------------------------------------------------------- // PRIVATE METHODS // ------------------------------------------------------------------------- private String extractHeaderValue( final String headerName, final MultivaluedMap headers) throws IllegalArgumentException { final String result = headers.getFirst(headerName); if (Strings.isNullOrEmpty(result)) { throw new IllegalArgumentException( "Request headers did not contain valid header field [" + headerName + "]"); } return result; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy