135 lines
4.5 KiB
Java
135 lines
4.5 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 monasca.api.infrastructure.servlet;
|
|
|
|
import java.io.IOException;
|
|
|
|
import javax.servlet.Filter;
|
|
import javax.servlet.FilterChain;
|
|
import javax.servlet.FilterConfig;
|
|
import javax.servlet.ServletException;
|
|
import javax.servlet.ServletOutputStream;
|
|
import javax.servlet.ServletRequest;
|
|
import javax.servlet.ServletResponse;
|
|
import javax.servlet.http.HttpServletResponse;
|
|
import javax.servlet.http.HttpServletResponseWrapper;
|
|
import javax.ws.rs.core.MediaType;
|
|
|
|
import org.eclipse.jetty.server.Response;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import monasca.api.resource.exception.Exceptions;
|
|
import monasca.api.resource.exception.Exceptions.FaultType;
|
|
|
|
/**
|
|
* 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 PreAuthenticationFilter implements Filter {
|
|
private static final Logger LOG = LoggerFactory.getLogger(PreAuthenticationFilter.class);
|
|
|
|
static class ErrorCapturingServletResponseWrapper extends HttpServletResponseWrapper {
|
|
private int statusCode;
|
|
private String errorMessage;
|
|
private Exception exception;
|
|
|
|
public ErrorCapturingServletResponseWrapper(HttpServletResponse response) {
|
|
super(response);
|
|
}
|
|
|
|
@Override
|
|
public void sendError(int statusCode) throws IOException {
|
|
this.statusCode = statusCode;
|
|
}
|
|
|
|
@Override
|
|
public void sendError(int statusCode, String msg) throws IOException {
|
|
this.statusCode = statusCode;
|
|
errorMessage = msg;
|
|
}
|
|
|
|
void sendError(int statusCode, String msg, Exception exception) throws IOException {
|
|
sendError(statusCode, msg);
|
|
this.exception = exception;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void destroy() {}
|
|
|
|
@Override
|
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
|
|
HttpServletResponse res = (HttpServletResponse) response;
|
|
ErrorCapturingServletResponseWrapper responseWrapper =
|
|
new ErrorCapturingServletResponseWrapper(res);
|
|
|
|
boolean caughtException = false;
|
|
ServletOutputStream out = null;
|
|
try {
|
|
out = res.getOutputStream();
|
|
chain.doFilter(request, responseWrapper);
|
|
if (responseWrapper.statusCode != 401 && responseWrapper.statusCode != 500)
|
|
return;
|
|
|
|
} catch (Exception e) {
|
|
LOG.error("Error while executing pre authentication filter", e);
|
|
caughtException = true;
|
|
}
|
|
|
|
try {
|
|
res.setContentType(MediaType.APPLICATION_JSON);
|
|
if (caughtException) {
|
|
res.setStatus(Response.SC_INTERNAL_SERVER_ERROR);
|
|
}
|
|
else {
|
|
res.setStatus(responseWrapper.statusCode);
|
|
FaultType faultType;
|
|
if (responseWrapper.statusCode == 500) {
|
|
faultType = FaultType.SERVER_ERROR;
|
|
}
|
|
else {
|
|
faultType = FaultType.UNAUTHORIZED;
|
|
}
|
|
String output = Exceptions.buildLoggedErrorMessage(faultType, responseWrapper.errorMessage,
|
|
null, responseWrapper.exception);
|
|
out.print(output);
|
|
}
|
|
} catch (IllegalArgumentException e) {
|
|
// CSMiddleware is throwing this error for invalid tokens.
|
|
// This problem appears to be fixed in other versions, but they are not approved yet.
|
|
try {
|
|
String output =
|
|
Exceptions.buildLoggedErrorMessage(FaultType.UNAUTHORIZED, "invalid authToken", null,
|
|
responseWrapper.exception);
|
|
out.print(output);
|
|
} catch (Exception x) {
|
|
LOG.error("Error while writing failed authentication HTTP response", x);
|
|
}
|
|
} catch (Exception e) {
|
|
LOG.error("Error while writing failed authentication HTTP response", e);
|
|
} finally {
|
|
if (out != null)
|
|
try {
|
|
out.close();
|
|
} catch (IOException ignore) {
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void init(FilterConfig filterConfig) throws ServletException {}
|
|
}
|