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

com.brightsparklabs.dropwizard.bundles.auth.external.ExternallyAuthenticatedAuthBundle 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 static java.util.Objects.requireNonNull;

import com.google.common.collect.ImmutableList;
import io.dropwizard.auth.AuthDynamicFeature;
import io.dropwizard.auth.AuthFilter;
import io.dropwizard.auth.AuthValueFactoryProvider;
import io.dropwizard.auth.AuthenticationException;
import io.dropwizard.auth.Authorizer;
import io.dropwizard.auth.PermitAllAuthorizer;
import io.dropwizard.core.ConfiguredBundle;
import io.dropwizard.core.setup.Bootstrap;
import io.dropwizard.core.setup.Environment;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
import jakarta.ws.rs.ext.ExceptionMapper;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.glassfish.jersey.server.filter.RolesAllowedDynamicFeature;

/**
 * Bundle to support authenticating users who have been already authenticated by an external system.
 *
 * @param  Type of configuration required to configure the bundle.
 * @param 

Type of {@link Principal} to return for authenticated users. * @author brightSPARK Labs */ public class ExternallyAuthenticatedAuthBundle< P extends Principal, T extends ExternallyAuthenticatedAuthBundleConfiguration> implements ConfiguredBundle { // ------------------------------------------------------------------------- // CONSTANTS // ------------------------------------------------------------------------- // ------------------------------------------------------------------------- // CLASS VARIABLES // ------------------------------------------------------------------------- // ------------------------------------------------------------------------- // INSTANCE VARIABLES // ------------------------------------------------------------------------- /** Type of {@link Principal} to return for authenticated users */ private final Class

principalClazz; /** Converter between {@link InternalUser} and the {@link Principal} used in the system. */ private final PrincipalConverter

principalConverter; /** Authorizer to use - will default to permit all */ private final Authorizer

authorizer; /** determines whether to allow dynamic, role based Authorization */ private final boolean setupRolesAllowedDynamicFeature; /** listeners for authentication events */ private final List authenticationEventListeners; // ------------------------------------------------------------------------- // CONSTRUCTION // ------------------------------------------------------------------------- /** * Constructor. This will default to PermitAll authorization. * * @param principalClazz Type of {@link Principal} to return for authenticated users * @param converter Converts the internal user to the {@link Principal} used in the system * @param listeners Listeners to notify on authentication events. */ public ExternallyAuthenticatedAuthBundle( final Class

principalClazz, final PrincipalConverter

converter, final AuthenticationEventListener... listeners) { this(principalClazz, converter, new PermitAllAuthorizer

(), false, listeners); } /** * Constructor. This will use the provided Authorizer, and register {@link * RolesAllowedDynamicFeature} * * @param principalClazz Type of {@link Principal} to return for authenticated users * @param converter Converter between {@link InternalUser} and the {@link Principal} used in the * system. * @param authorizer the {@link Authorizer} to use. * @param listeners Listeners to notify on authentication events. */ public ExternallyAuthenticatedAuthBundle( final Class

principalClazz, final PrincipalConverter

converter, final Authorizer

authorizer, final AuthenticationEventListener... listeners) { this(principalClazz, converter, authorizer, true, listeners); } /** * Constructor for an AuthBundle that uses an {@link InternalUser} as principal. This will * default to PermitAll authorization. * * @param listeners The authentication event listeners */ public ExternallyAuthenticatedAuthBundle(final AuthenticationEventListener... listeners) { this(new PermitAllAuthorizer<>(), false, listeners); } /** * Constructor for an AuthBundle that uses an {@link InternalUser} as principal. This will use * the provided Authorizer, and register {@link RolesAllowedDynamicFeature} * * @param authorizer the {@link Authorizer} to use. * @param listeners The authentication event listeners */ public ExternallyAuthenticatedAuthBundle( final Authorizer authorizer, final AuthenticationEventListener... listeners) { this(authorizer, true, listeners); } /** * Private Constructor for {@link ExternallyAuthenticatedAuthBundle} that use {@link * InternalUser} as the principal. * * @param authorizer the {@link Authorizer} to use. * @param setupRolesAllowedDynamicFeature determines whether to allow dynamic, role based * Authorization * @param listeners The authentication event listeners */ private ExternallyAuthenticatedAuthBundle( final Authorizer authorizer, final boolean setupRolesAllowedDynamicFeature, final AuthenticationEventListener... listeners) { this( (Class

) InternalUser.class, (PrincipalConverter

) new IdentityPrincipalConverter(), (Authorizer

) authorizer, setupRolesAllowedDynamicFeature, listeners); } /** * Private Constructor, for convenience. * * @param principalClazz Type of {@link Principal} to return for authenticated users * @param converter Converter between {@link InternalUser} and the {@link Principal} used in the * system. * @param authorizer the {@link Authorizer} to use. * @param setupRolesAllowedDynamicFeature determines whether to allow dynamic, role based * Authorization * @param listeners Listeners to notify on authentication events. */ private ExternallyAuthenticatedAuthBundle( final Class

principalClazz, final PrincipalConverter

converter, final Authorizer

authorizer, final boolean setupRolesAllowedDynamicFeature, final AuthenticationEventListener... listeners) { this.principalClazz = principalClazz; this.principalConverter = requireNonNull(converter); this.authorizer = requireNonNull(authorizer); this.setupRolesAllowedDynamicFeature = setupRolesAllowedDynamicFeature; this.authenticationEventListeners = new ArrayList<>(Arrays.asList(listeners)); } // ------------------------------------------------------------------------- // PUBLIC METHODS // ------------------------------------------------------------------------- @Override public void initialize(final Bootstrap bootstrap) {} @Override public void run(final T configuration, final Environment environment) throws Exception { final ExternallyAuthenticatedAuthFilterFactory authFilterFactory = configuration.getExternallyAuthenticatedFilterFactory(); // Handle authentication exceptions. environment.jersey().register(new AuthenticationExceptionMapper()); environment.jersey().register(new AuthenticationDeniedExceptionMapper()); // Add the user authentication to the request environment .jersey() .register( new AddUserAuthToRequestFilter<>( principalConverter, configuration .getExternallyAuthenticatedFilterFactory() .getMdcUsernameField())); final AuthFilter authFilter = authFilterFactory.build( principalConverter, authorizer, authenticationEventListeners); environment.jersey().register(new AuthDynamicFeature(authFilter)); // Support using @Auth to inject a custom Principal type into resources. environment.jersey().register(new AuthValueFactoryProvider.Binder<>(principalClazz)); // Allow dynamic authorization. if (setupRolesAllowedDynamicFeature) { environment.jersey().register(RolesAllowedDynamicFeature.class); } } // ------------------------------------------------------------------------- // PUBLIC METHODS // ------------------------------------------------------------------------- /** * Add an authentication listener * * @param listener the listener to add */ public void addAuthenticationEventListener(final AuthenticationEventListener listener) { final AuthenticationEventListener safeListener = requireNonNull(listener); this.authenticationEventListeners.add(safeListener); } /** * Removes an authentication listener * * @param listener the listener to remove */ public void removeAuthenticationEventListener(final AuthenticationEventListener listener) { final AuthenticationEventListener safeListener = requireNonNull(listener); this.authenticationEventListeners.remove(safeListener); } /** * Get the authentication listeners * * @return the authentication listeners */ public List getAuthenticationEventListeners() { return ImmutableList.copyOf(this.authenticationEventListeners); } // ------------------------------------------------------------------------- // PRIVATE METHODS // ------------------------------------------------------------------------- // ------------------------------------------------------------------------- // INNER CLASSES // ------------------------------------------------------------------------- /** Maps the {@link AuthenticationException} to a {@link Status#UNAUTHORIZED}. */ private static class AuthenticationExceptionMapper implements ExceptionMapper { @Override public Response toResponse(final AuthenticationException exception) { return Response.status(Status.UNAUTHORIZED).build(); } } /** Maps the {@link AuthenticationException} to a {@link Status#UNAUTHORIZED}. */ private static class AuthenticationDeniedExceptionMapper implements ExceptionMapper { @Override public Response toResponse(final AuthenticationDeniedException exception) { return Response.status(Status.UNAUTHORIZED).build(); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy