return back http error code instead of java stacktrace when no tenant identifier is provided in request.

This commit is contained in:
Keith Woodlock
2012-07-16 17:57:20 +01:00
parent 983a61e939
commit 9e019aa7de
3 changed files with 69 additions and 16 deletions
@@ -52,6 +52,18 @@ public class ApiGlobalErrorResponse {
return globalErrorResponse;
}
public static ApiGlobalErrorResponse invalidTenantIdentifier() {
ApiGlobalErrorResponse globalErrorResponse = new ApiGlobalErrorResponse();
globalErrorResponse.setHttpStatusCode("401");
globalErrorResponse.setDeveloperMessage("Invalid tenant details were passed in api request.");
globalErrorResponse.setDeveloperDocLink("https://github.com/keithwoodlock/mifosx/wiki/HTTP-API-Error-codes");
globalErrorResponse.setUserMessageGlobalisationCode("error.msg.invalid.tenant.identifier");
globalErrorResponse.setDefaultUserMessage("Invalide tenant identifier provided with request.");
return globalErrorResponse;
}
public static ApiGlobalErrorResponse unAuthorized() {
ApiGlobalErrorResponse globalErrorResponse = new ApiGlobalErrorResponse();
@@ -0,0 +1,28 @@
package org.mifosng.platform.api.errorhandling;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
import org.mifosng.platform.api.data.ApiGlobalErrorResponse;
import org.mifosng.platform.infrastructure.InvalidTenantIdentiferException;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
/**
* An {@link ExceptionMapper} to map {@link InvalidTenantIdentiferException} thrown by platform during authentication into a HTTP API friendly format.
*
* The {@link InvalidTenantIdentiferException} is thrown by spring security on platform when a request contains an invalid tenant identifier.
*/
@Provider
@Component
@Scope("singleton")
public class InvalidTenantIdentifierExceptionMapper implements ExceptionMapper<InvalidTenantIdentiferException> {
@Override
public Response toResponse(final InvalidTenantIdentiferException e) {
return Response.status(Status.UNAUTHORIZED).entity(ApiGlobalErrorResponse.invalidTenantIdentifier()).type(MediaType.APPLICATION_JSON).build();
}
}
@@ -7,11 +7,12 @@ import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedCredentialsNotFoundException;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
/**
@@ -31,25 +32,37 @@ public class TenantAwareBasicAuthenticationFilter extends BasicAuthenticationFil
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
// ignore to allow 'preflight' requests from AJAX applications in different domain
} else {
try {
final String tenantId = request.getHeader(tenantRequestHeader);
if (tenantId == null && exceptionIfHeaderMissing) {
throw new PreAuthenticatedCredentialsNotFoundException(tenantRequestHeader + " header not found in request.");
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
// ignore to allow 'preflight' requests from AJAX applications in different domain
} else {
final String tenantId = request.getHeader(tenantRequestHeader);
if (tenantId == null && exceptionIfHeaderMissing) {
throw new InvalidTenantIdentiferException(tenantRequestHeader + " header not found in request.");
}
// check tenants database for tenantId
MifosPlatformTenant tenant = this.tenantDetailsService.loadTenantById(tenantId);
ThreadLocalContextUtil.setTenant(tenant);
}
// check tenants database for tenantId
MifosPlatformTenant tenant = this.tenantDetailsService.loadTenantById(tenantId);
ThreadLocalContextUtil.setTenant(tenant);
}
super.doFilter(req, res, chain);
super.doFilter(req, res, chain);
} catch (InvalidTenantIdentiferException e) {
// deal with exception at low level
SecurityContextHolder.getContext().setAuthentication(null);
response.addHeader("WWW-Authenticate", "Basic realm=\"" + "Mifos Platform API" + "\"");
response.sendError(HttpServletResponse.SC_BAD_REQUEST, tenantRequestHeader + " header not found in request.");
} finally {
}
}
}