mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-05-31 09:12:14 +00:00
Take another apporach and throw all unhandled exceptions wrapped in a ServletException
This commit is contained in:
parent
e8de53b87c
commit
30f6871124
@ -13,5 +13,16 @@
|
||||
<description>Acegi Security System for Spring - Support for WebWork 2</description>
|
||||
<version>0.1-SNAPSHOT</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>opensymphony</groupId>
|
||||
<artifactId>webwork</artifactId>
|
||||
<version>2.2.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>2.4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
@ -14,18 +14,27 @@
|
||||
*/
|
||||
package org.acegisecurity.webwork;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.acegisecurity.AccessDeniedException;
|
||||
import org.acegisecurity.AcegiSecurityException;
|
||||
import org.acegisecurity.AuthenticationException;
|
||||
import org.acegisecurity.ui.ExceptionTranslationFilter;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import com.opensymphony.webwork.ServletActionContext;
|
||||
import com.opensymphony.webwork.dispatcher.DispatcherUtils;
|
||||
import com.opensymphony.webwork.dispatcher.mapper.ActionMapping;
|
||||
import com.opensymphony.xwork.ActionContext;
|
||||
import com.opensymphony.xwork.ActionProxy;
|
||||
import com.opensymphony.xwork.ActionProxyFactory;
|
||||
import com.opensymphony.xwork.Result;
|
||||
import com.opensymphony.xwork.config.ConfigurationException;
|
||||
import com.opensymphony.xwork.util.OgnlValueStack;
|
||||
import com.opensymphony.xwork.util.XWorkContinuationConfig;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@ -43,51 +52,81 @@ import com.opensymphony.webwork.dispatcher.DispatcherUtils;
|
||||
*/
|
||||
public class AcegiDispatcherUtils extends DispatcherUtils {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(AcegiDispatcherUtils.class);
|
||||
|
||||
protected AcegiDispatcherUtils(ServletContext servletContext) {
|
||||
super(servletContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an HTTP error response code on any exception that it's no an Acegi {@link AuthenticationException} or
|
||||
* {@link AccessDeniedException}
|
||||
* <p>
|
||||
* Loads the action and executes it. This method first creates the action context from the given parameters then
|
||||
* loads an <tt>ActionProxy</tt> from the given action name and namespace. After that, the action is executed and
|
||||
* output channels throught the response object. Actions not found are sent back to the user via the
|
||||
* {@link DispatcherUtils#sendError} method, using the 404 return code. All other errors are reported by throwing a
|
||||
* ServletException.
|
||||
* </p>
|
||||
*
|
||||
* @param request the HttpServletRequest object.
|
||||
* @param response the HttpServletResponse object.
|
||||
* @param code the HttpServletResponse error code (see {@link javax.servlet.http.HttpServletResponse} for possible
|
||||
* error codes).
|
||||
* @param e the Exception that is reported.
|
||||
* <p>
|
||||
* Difference between this and WebWork prvided class is that any unhandled exception will be thrown instead of
|
||||
* processed inside WebWork.
|
||||
* </p>
|
||||
*
|
||||
* @param request the HttpServletRequest object
|
||||
* @param response the HttpServletResponse object
|
||||
* @param mapping the action mapping object
|
||||
* @throws ServletException when an unknown error occurs (not a 404, but typically something that would end up as a
|
||||
* 5xx by the servlet container)
|
||||
*/
|
||||
public void sendError(HttpServletRequest request, HttpServletResponse response, ServletContext ctx, int code,
|
||||
Exception e) {
|
||||
if (devMode) {
|
||||
super.sendError(request, response, ctx, code, e);
|
||||
} else {
|
||||
try {
|
||||
// send a http error response to use the servlet defined error handler
|
||||
// make the exception availible to the web.xml defined error page
|
||||
request.setAttribute("javax.servlet.error.exception", e);
|
||||
public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context,
|
||||
ActionMapping mapping) throws ServletException {
|
||||
Map extraContext = createContextMap(request, response, mapping, context);
|
||||
|
||||
// for compatibility
|
||||
request.setAttribute("javax.servlet.jsp.jspException", e);
|
||||
// If there was a previous value stack, then create a new copy and pass it in to be used by the new Action
|
||||
OgnlValueStack stack = (OgnlValueStack) request.getAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY);
|
||||
if (stack != null) {
|
||||
extraContext.put(ActionContext.VALUE_STACK, new OgnlValueStack(stack));
|
||||
}
|
||||
|
||||
// do not send the error response if it's an acegi exception
|
||||
if (!isAcegiSecurityException(e)) {
|
||||
response.sendError(code, e.getMessage());
|
||||
}
|
||||
} catch (IOException e1) {
|
||||
// we're already sending an error, not much else we can do if more stuff breaks
|
||||
try {
|
||||
String namespace = mapping.getNamespace();
|
||||
String name = mapping.getName();
|
||||
String method = mapping.getMethod();
|
||||
|
||||
String id = request.getParameter(XWorkContinuationConfig.CONTINUE_PARAM);
|
||||
if (id != null) {
|
||||
// remove the continue key from the params - we don't want to bother setting
|
||||
// on the value stack since we know it won't work. Besides, this breaks devMode!
|
||||
Map params = (Map) extraContext.get(ActionContext.PARAMETERS);
|
||||
params.remove(XWorkContinuationConfig.CONTINUE_PARAM);
|
||||
|
||||
// and now put the key in the context to be picked up later by XWork
|
||||
extraContext.put(XWorkContinuationConfig.CONTINUE_KEY, id);
|
||||
}
|
||||
|
||||
ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy(namespace, name, extraContext, true,
|
||||
false);
|
||||
proxy.setMethod(method);
|
||||
request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY, proxy.getInvocation().getStack());
|
||||
|
||||
// if the ActionMapping says to go straight to a result, do it!
|
||||
if (mapping.getResult() != null) {
|
||||
Result result = mapping.getResult();
|
||||
result.execute(proxy.getInvocation());
|
||||
} else {
|
||||
proxy.execute();
|
||||
}
|
||||
|
||||
// If there was a previous value stack then set it back onto the request
|
||||
if (stack != null) {
|
||||
request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY, stack);
|
||||
}
|
||||
} catch (ConfigurationException e) {
|
||||
LOG.error("Could not find action", e);
|
||||
sendError(request, response, context, HttpServletResponse.SC_NOT_FOUND, e);
|
||||
} catch (Exception e) {
|
||||
throw new ServletException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an object is an {@link AcegiSecurityException}.
|
||||
*
|
||||
* @param o any object or <code>null</code>
|
||||
* @return true if the object passed is an {@link AuthenticationException} or {@link AccessDeniedException}
|
||||
*/
|
||||
private boolean isAcegiSecurityException(Object o) {
|
||||
return ((o != null) && ((o instanceof AuthenticationException || o instanceof AccessDeniedException)));
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user