001/*
002 * The contents of this file are subject to the license and copyright
003 * detailed in the LICENSE and NOTICE files at the root of the source
004 * tree.
005 */
006package org.fcrepo.auth.common;
007
008import static java.util.Collections.emptySet;
009
010import org.slf4j.Logger;
011import org.slf4j.LoggerFactory;
012
013import javax.servlet.http.HttpServletRequest;
014
015import java.security.Principal;
016import java.util.HashSet;
017import java.util.Set;
018
019/**
020 * An example principal provider that extracts principals from request headers.
021 *
022 * @author Gregory Jansen
023 * @author Mike Daines
024 * @see PrincipalProvider
025 */
026public class HttpHeaderPrincipalProvider extends AbstractPrincipalProvider {
027
028    public static class HttpHeaderPrincipal implements Principal {
029
030        private final String name;
031
032        protected HttpHeaderPrincipal(final String name) {
033            this.name = name;
034        }
035
036        @Override
037        public String getName() {
038            return name;
039        }
040
041        @Override
042        public String toString() {
043            return name;
044        }
045
046        @Override
047        public boolean equals(final Object o) {
048            if (o instanceof HttpHeaderPrincipal) {
049                return ((HttpHeaderPrincipal) o).getName().equals(
050                        this.getName());
051            }
052            return false;
053        }
054
055        @Override
056        public int hashCode() {
057            if (name == null) {
058                return 0;
059            }
060            return name.hashCode();
061        }
062
063    }
064
065    private String headerName;
066
067    private String separator = "";
068
069    private static final Logger LOGGER = LoggerFactory.getLogger(HttpHeaderPrincipalProvider.class);
070
071    /**
072     * @param headerName The name of the header from which to extract principals
073     */
074    public void setHeaderName(final String headerName) {
075        this.headerName = headerName;
076    }
077
078    /**
079     * @param separator The string by which to split header values
080     */
081    public void setSeparator(final String separator) {
082        this.separator = separator;
083    }
084
085    /*
086    * (non-Javadoc)
087    * @see
088    * org.fcrepo.auth.PrincipalProvider#getPrincipals(javax.servlet.http.HttpServletRequest)
089    */
090    @Override
091    public Set<Principal> getPrincipals(final HttpServletRequest request) {
092        LOGGER.debug("Checking for principals using {}", HttpHeaderPrincipalProvider.class.getSimpleName());
093
094        if (headerName == null || separator == null) {
095            LOGGER.debug("headerName or separator not initialized");
096            return emptySet();
097        }
098
099        LOGGER.debug("Trying to get principals from header: {}; separator: {}", headerName, separator);
100
101        if (request == null) {
102            LOGGER.debug("Servlet request from servletCredentials was null");
103            return emptySet();
104        }
105
106        final String value = request.getHeader(headerName);
107
108        if (value == null) {
109            LOGGER.debug("Value for header {} is null", headerName);
110            return emptySet();
111        }
112
113        final String[] names = value.split(separator);
114
115        final Set<Principal> principals = new HashSet<>();
116
117        for (final String name : names) {
118            LOGGER.debug("Adding HTTP header-provided principal: {}", name.trim());
119            principals.add(createPrincipal(name));
120        }
121
122        return principals;
123
124    }
125
126    protected Principal createPrincipal(final String name) {
127        return new HttpHeaderPrincipal(name.trim());
128    }
129
130}