/*
* Licensed to DuraSpace under one or more contributor license agreements.
* See the NOTICE file distributed with this work for additional information
* regarding copyright ownership.
*
* DuraSpace licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.fcrepo.http.commons.test.util;
import static java.lang.reflect.Proxy.newProxyInstance;
import static java.util.Collections.emptySet;
import static java.util.Collections.singleton;
import static javax.ws.rs.core.HttpHeaders.AUTHORIZATION;
import static org.slf4j.LoggerFactory.getLogger;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.security.Principal;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.WebApplicationException;
import org.glassfish.grizzly.http.server.GrizzlyPrincipal;
import org.glassfish.jersey.internal.util.Base64;
import org.slf4j.Logger;
/**
* @author Gregory Jansen
*/
public class TestAuthenticationRequestFilter implements Filter {
private static final Logger log = getLogger(TestAuthenticationRequestFilter.class);
private static final String FEDORA_ADMIN_USER = "fedoraAdmin";
/*
* (non-Javadoc)
* @see
* com.sun.jersey.spi.container.ContainerRequestFilter#filter(com.sun.jersey
* .spi.container.ContainerRequest)
*/
@Override
public void doFilter(final ServletRequest request,
final ServletResponse response, final FilterChain chain)
throws IOException, ServletException {
final HttpServletRequest req = (HttpServletRequest) request;
final String username = getUsername(req);
// Validate the extracted credentials
Set<String> containerRoles = emptySet();
if (FEDORA_ADMIN_USER.equals(username)) {
containerRoles = singleton("fedoraAdmin");
log.debug("ADMIN AUTHENTICATED");
} else {
containerRoles = singleton("fedoraUser");
log.debug("USER AUTHENTICATED");
}
final ServletRequest proxy = proxy(req, username, containerRoles);
chain.doFilter(proxy, response);
}
/**
* @param request
* @param username
* @param containerRoles
* @return
*/
private static ServletRequest proxy(final HttpServletRequest request,
final String username, final Set<String> containerRoles) {
final Principal user = new GrizzlyPrincipal(username);
final HttpServletRequest result =
(HttpServletRequest) newProxyInstance(request.getClass()
.getClassLoader(),
new Class[] {HttpServletRequest.class},
new InvocationHandler() {
@Override
public Object invoke(final Object proxy,
final Method method, final Object[] args)
throws Throwable {
if (method.getName().equals("isUserInRole")) {
final String role = (String) args[0];
return containerRoles.contains(role);
} else if (method.getName().equals(
"getUserPrincipal")) {
return user;
} else if (method.getName().equals(
"getRemoteUser")) {
return username;
}
return method.invoke(request, args);
}
});
return result;
}
private static String getUsername(final HttpServletRequest request) {
// Extract authentication credentials
String authentication = request.getHeader(AUTHORIZATION);
if (authentication == null) {
return null;
}
if (!authentication.startsWith("Basic ")) {
return null;
}
authentication = authentication.substring("Basic ".length());
final String[] values = Base64.decodeAsString(authentication).split(":");
if (values.length < 2) {
throw new WebApplicationException(400);
// "Invalid syntax for username and password"
}
final String username = values[0];
final String password = values[1];
if ((username == null) || (password == null)) {
return null;
}
return username;
}
/*
* (non-Javadoc)
* @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
*/
@Override
public void init(final FilterConfig filterConfig) {
}
/*
* (non-Javadoc)
* @see javax.servlet.Filter#destroy()
*/
@Override
public void destroy() {
}
}