172 lines
6.0 KiB
Java
172 lines
6.0 KiB
Java
/*
|
|
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
|
*
|
|
* Licensed 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 com.hpcloud.mon.infrastructure.servlet;
|
|
|
|
import java.io.IOException;
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.Enumeration;
|
|
import java.util.List;
|
|
|
|
import javax.annotation.Nullable;
|
|
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.servlet.http.HttpServletRequestWrapper;
|
|
import javax.servlet.http.HttpServletResponse;
|
|
import javax.ws.rs.core.MediaType;
|
|
|
|
import com.hpcloud.mon.infrastructure.servlet.PreAuthenticationFilter.ErrorCapturingServletResponseWrapper;
|
|
|
|
/**
|
|
* Authenticates requests using header information from the CsMiddleware. Provides the X-TENANT-ID
|
|
* servlet attribute as a request header. Intended to be added to a servlet filter chain after the
|
|
* CsMiddleware TokenAuth filter.
|
|
*/
|
|
public class PostAuthenticationFilter implements Filter {
|
|
static final String CONFIRMED_STATUS = "CONFIRMED";
|
|
static final String X_ROLES_ATTRIBUTE = "X-ROLES";
|
|
static final String X_IDENTITY_STATUS_ATTRIBUTE = "X-IDENTITY-STATUS";
|
|
private static final String X_TENANT_ID_ATTRIBUTE = "X-PROJECT-ID";//X-TENANT-ID";
|
|
static final String X_TENANT_ID_HEADER = "X-Tenant-Id";
|
|
|
|
private final List<String> rolesToMatch = new ArrayList<String>();
|
|
|
|
public PostAuthenticationFilter(List<String> rolesToMatch) {
|
|
for (String role : rolesToMatch)
|
|
this.rolesToMatch.add(role.toLowerCase());
|
|
}
|
|
|
|
@Override
|
|
public void destroy() {
|
|
}
|
|
|
|
@Override
|
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
|
|
final HttpServletRequest req = (HttpServletRequest) request;
|
|
ErrorCapturingServletResponseWrapper res = (ErrorCapturingServletResponseWrapper) response;
|
|
String tenantIdStr = null;
|
|
|
|
try {
|
|
Object tenantId = request.getAttribute(X_TENANT_ID_ATTRIBUTE);
|
|
Object projectId = request.getAttribute("X-PROJECT-ID");
|
|
tenantId= projectId;
|
|
/*while(request.getAttributeNames().hasMoreElements()) {
|
|
System.out.println(request.getAttributeNames().nextElement());
|
|
|
|
} */
|
|
System.out.println("this is the project id:"+projectId);
|
|
System.out.println("This is the tenantId"+tenantId);
|
|
if (tenantId == null)
|
|
sendAuthError(res, null, null, null);
|
|
tenantIdStr = tenantId.toString();
|
|
|
|
boolean authenticated = isAuthenticated(req);
|
|
boolean authorized = isAuthorized(req);
|
|
|
|
if (authenticated && authorized) {
|
|
HttpServletRequestWrapper wrapper = requestWrapperFor(req);
|
|
chain.doFilter(wrapper, response);
|
|
return;
|
|
}
|
|
|
|
if (authorized)
|
|
sendAuthError(res, tenantIdStr, null, null);
|
|
else
|
|
sendAuthError(res, tenantIdStr, "Tenant is missing a required role to access this service",
|
|
null);
|
|
} catch (Exception e) {
|
|
try {
|
|
sendAuthError(res, tenantIdStr, null, e);
|
|
} catch (IOException ignore) {
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void init(FilterConfig filterConfig) throws ServletException {
|
|
}
|
|
|
|
/**
|
|
* @return true if the request is authenticated else false
|
|
*/
|
|
private boolean isAuthenticated(HttpServletRequest request) {
|
|
Object identityStatus = request.getAttribute(X_IDENTITY_STATUS_ATTRIBUTE);
|
|
return identityStatus != null && CONFIRMED_STATUS.equalsIgnoreCase(identityStatus.toString());
|
|
}
|
|
|
|
/**
|
|
* @return true if the request is authorized else false
|
|
*/
|
|
private boolean isAuthorized(HttpServletRequest request) {
|
|
Object roles = request.getAttribute(X_ROLES_ATTRIBUTE);
|
|
if (roles == null)
|
|
return false;
|
|
|
|
for (String role : roles.toString().split(","))
|
|
if (rolesToMatch.contains(role.toLowerCase()))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Returns an HttpServletRequestWrapper that serves tenant id headers from request attributes.
|
|
*/
|
|
private HttpServletRequestWrapper requestWrapperFor(final HttpServletRequest request) {
|
|
return new HttpServletRequestWrapper(request) {
|
|
@Override
|
|
public String getHeader(String name) {
|
|
if (name.equalsIgnoreCase(X_TENANT_ID_HEADER))
|
|
return request.getAttribute(X_TENANT_ID_ATTRIBUTE).toString();
|
|
return super.getHeader(name);
|
|
}
|
|
|
|
@Override
|
|
public Enumeration<String> getHeaderNames() {
|
|
List<String> names = Collections.list(super.getHeaderNames());
|
|
names.add(X_TENANT_ID_HEADER);
|
|
return Collections.enumeration(names);
|
|
}
|
|
|
|
@Override
|
|
public Enumeration<String> getHeaders(String name) {
|
|
if (name.equalsIgnoreCase(X_TENANT_ID_HEADER))
|
|
return Collections.enumeration(Collections.singleton(request.getAttribute(
|
|
X_TENANT_ID_ATTRIBUTE).toString()));
|
|
return super.getHeaders(name);
|
|
}
|
|
};
|
|
}
|
|
|
|
private void sendAuthError(ErrorCapturingServletResponseWrapper response,
|
|
@Nullable String tenantId, @Nullable String message, @Nullable Exception exception)
|
|
throws IOException {
|
|
response.setContentType(MediaType.APPLICATION_JSON);
|
|
|
|
if (message == null)
|
|
response.sendError(HttpServletResponse.SC_UNAUTHORIZED,
|
|
tenantId == null ? "Failed to authenticate request"
|
|
: "Failed to authenticate request for " + tenantId, exception);
|
|
else
|
|
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, String.format(message, tenantId));
|
|
}
|
|
}
|