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.modeshape.jcr.api.ServletCredentials;
023import org.slf4j.Logger;
024import org.slf4j.LoggerFactory;
025
026import javax.jcr.Credentials;
027import javax.servlet.http.HttpServletRequest;
028
029import java.security.Principal;
030import java.util.HashSet;
031import java.util.Set;
032
033/**
034 * An example principal provider that extracts principals from request headers.
035 *
036 * @author Gregory Jansen
037 * @author Mike Daines
038 * @see PrincipalProvider
039 */
040public class HttpHeaderPrincipalProvider implements PrincipalProvider {
041
042    protected static class HttpHeaderPrincipal implements Principal {
043
044        private final String name;
045
046        HttpHeaderPrincipal(final String name) {
047            this.name = name;
048        }
049
050        @Override
051        public String getName() {
052            return name;
053        }
054
055        @Override
056        public String toString() {
057            return name;
058        }
059
060        @Override
061        public boolean equals(final Object o) {
062            if (o instanceof HttpHeaderPrincipal) {
063                return ((HttpHeaderPrincipal) o).getName().equals(
064                        this.getName());
065            }
066            return false;
067        }
068
069        @Override
070        public int hashCode() {
071            if (name == null) {
072                return 0;
073            }
074            return name.hashCode();
075        }
076
077    }
078
079    private String headerName;
080
081    private String separator = "";
082
083    private static final Logger LOGGER = LoggerFactory.getLogger(HttpHeaderPrincipalProvider.class);
084
085    /**
086     * @param headerName The name of the header from which to extract principals
087     */
088    public void setHeaderName(final String headerName) {
089        this.headerName = headerName;
090    }
091
092    /**
093     * @param separator The string by which to split header values
094     */
095    public void setSeparator(final String separator) {
096        this.separator = separator;
097    }
098
099    /*
100     * (non-Javadoc)
101     * @see
102     * org.fcrepo.auth.PrincipalProvider#getPrincipals(javax.jcr.Credentials)
103     */
104    @Override
105    public Set<Principal> getPrincipals(final Credentials credentials) {
106        LOGGER.debug("Checking for principals using {}", HttpHeaderPrincipalProvider.class.getSimpleName());
107
108        if (headerName == null || separator == null) {
109            LOGGER.debug("headerName or separator not initialized");
110            return emptySet();
111        }
112
113        LOGGER.debug("Trying to get principals from header: {}; separator: {}", headerName, separator);
114
115        if (!(credentials instanceof ServletCredentials)) {
116            LOGGER.debug("Credentials is not an instanceof ServletCredentials");
117            return emptySet();
118        }
119
120        final ServletCredentials servletCredentials =
121                (ServletCredentials) credentials;
122
123        final HttpServletRequest request = servletCredentials.getRequest();
124
125        if (request == null) {
126            LOGGER.debug("Servlet request from servletCredentials was null");
127            return emptySet();
128        }
129
130        final String value = request.getHeader(headerName);
131
132        if (value == null) {
133            LOGGER.debug("Value for header {} is null", headerName);
134            return emptySet();
135        }
136
137        final String[] names = value.split(separator);
138
139        final Set<Principal> principals = new HashSet<>();
140
141        for (final String name : names) {
142            LOGGER.debug("Adding HTTP header-provided principal: {}", name.trim());
143            principals.add(new HttpHeaderPrincipal(name.trim()));
144        }
145
146        return principals;
147
148    }
149
150}