001/*
002 * Licensed to DuraSpace under one or more contributor license agreements.
003 * See the NOTICE file distributed with this work for additional information
004 * regarding copyright ownership.
005 *
006 * DuraSpace licenses this file to you under the Apache License,
007 * Version 2.0 (the "License"); you may not use this file except in
008 * compliance with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.fcrepo.auth.common;
019
020import static java.util.Collections.emptySet;
021
022import org.slf4j.Logger;
023import org.slf4j.LoggerFactory;
024
025import javax.servlet.http.HttpServletRequest;
026
027import java.security.Principal;
028import java.util.HashSet;
029import java.util.Set;
030
031/**
032 * An example principal provider that extracts principals from request headers.
033 *
034 * @author Gregory Jansen
035 * @author Mike Daines
036 * @see PrincipalProvider
037 */
038public class HttpHeaderPrincipalProvider extends AbstractPrincipalProvider {
039
040    public static class HttpHeaderPrincipal implements Principal {
041
042        private final String name;
043
044        protected HttpHeaderPrincipal(final String name) {
045            this.name = name;
046        }
047
048        @Override
049        public String getName() {
050            return name;
051        }
052
053        @Override
054        public String toString() {
055            return name;
056        }
057
058        @Override
059        public boolean equals(final Object o) {
060            if (o instanceof HttpHeaderPrincipal) {
061                return ((HttpHeaderPrincipal) o).getName().equals(
062                        this.getName());
063            }
064            return false;
065        }
066
067        @Override
068        public int hashCode() {
069            if (name == null) {
070                return 0;
071            }
072            return name.hashCode();
073        }
074
075    }
076
077    private String headerName;
078
079    private String separator = "";
080
081    private static final Logger LOGGER = LoggerFactory.getLogger(HttpHeaderPrincipalProvider.class);
082
083    /**
084     * @param headerName The name of the header from which to extract principals
085     */
086    public void setHeaderName(final String headerName) {
087        this.headerName = headerName;
088    }
089
090    /**
091     * @param separator The string by which to split header values
092     */
093    public void setSeparator(final String separator) {
094        this.separator = separator;
095    }
096
097    /*
098    * (non-Javadoc)
099    * @see
100    * org.fcrepo.auth.PrincipalProvider#getPrincipals(javax.servlet.http.HttpServletRequest)
101    */
102    @Override
103    public Set<Principal> getPrincipals(final HttpServletRequest request) {
104        LOGGER.debug("Checking for principals using {}", HttpHeaderPrincipalProvider.class.getSimpleName());
105
106        if (headerName == null || separator == null) {
107            LOGGER.debug("headerName or separator not initialized");
108            return emptySet();
109        }
110
111        LOGGER.debug("Trying to get principals from header: {}; separator: {}", headerName, separator);
112
113        if (request == null) {
114            LOGGER.debug("Servlet request from servletCredentials was null");
115            return emptySet();
116        }
117
118        final String value = request.getHeader(headerName);
119
120        if (value == null) {
121            LOGGER.debug("Value for header {} is null", headerName);
122            return emptySet();
123        }
124
125        final String[] names = value.split(separator);
126
127        final Set<Principal> principals = new HashSet<>();
128
129        for (final String name : names) {
130            LOGGER.debug("Adding HTTP header-provided principal: {}", name.trim());
131            principals.add(createPrincipal(name));
132        }
133
134        return principals;
135
136    }
137
138    protected Principal createPrincipal(final String name) {
139        return new HttpHeaderPrincipal(name.trim());
140    }
141
142}