dropwizard/dropwizard

View on GitHub
dropwizard-auth/src/main/java/io/dropwizard/auth/chained/ChainedAuthFilter.java

Summary

Maintainability
A
1 hr
Test Coverage
package io.dropwizard.auth.chained;

import io.dropwizard.auth.AuthFilter;

import javax.annotation.Priority;
import javax.ws.rs.Priorities;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.core.SecurityContext;
import java.io.IOException;
import java.security.Principal;
import java.util.List;

/**
 * Chains together authFilters, short circuits when the first filter
 * successfully authenticates
 *
 * N.B. AuthFilters can be chained together as long as they produce the same type
 * of Principal. This is not enforced by the type system at compile time, using
 * inconsistent principals will lead to runtime errors
 *
 * There is no requirement for the filters that are chained to use the same type for credentials.
 * The reason is that the ChainedFilter delegates to a filter which encapsulates
 * the authenticator and credential type
 *
 *
 * @param <C> the type of Credentials to be authenticated
 * @param <P> the type of the Principal
 */
@Priority(Priorities.AUTHENTICATION)
public class ChainedAuthFilter<C, P extends Principal> extends AuthFilter<C, P> {
    @SuppressWarnings("rawtypes")
    private final List<AuthFilter> handlers;

    public ChainedAuthFilter(@SuppressWarnings("rawtypes") List<AuthFilter> handlers) {
        this.handlers = handlers;
    }

    @Override
    public void filter(ContainerRequestContext containerRequestContext) throws IOException {
        WebApplicationException firstException = null;
        for (@SuppressWarnings("rawtypes") AuthFilter authFilter : handlers) {
            final SecurityContext securityContext = containerRequestContext.getSecurityContext();
            try {
                authFilter.filter(containerRequestContext);
                if (securityContext != containerRequestContext.getSecurityContext()) {
                    return;
                }
            } catch (WebApplicationException e) {
                if (firstException == null) {
                    firstException = e;
                }
            }
        }

        if (firstException == null) {
            throw new WebApplicationException(unauthorizedHandler.buildResponse(prefix, realm));
        }
        throw firstException;
    }
}