|
|
|
|
@ -14,18 +14,27 @@
@@ -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;
@@ -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> |
|
|
|
|
* |
|
|
|
|
* <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 code the HttpServletResponse error code (see {@link javax.servlet.http.HttpServletResponse} for possible |
|
|
|
|
* error codes). |
|
|
|
|
* @param e the Exception that is reported. |
|
|
|
|
* @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); |
|
|
|
|
|
|
|
|
|
// for compatibility
|
|
|
|
|
request.setAttribute("javax.servlet.jsp.jspException", e); |
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
} |
|
|
|
|
public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context, |
|
|
|
|
ActionMapping mapping) throws ServletException { |
|
|
|
|
Map extraContext = createContextMap(request, response, mapping, context); |
|
|
|
|
|
|
|
|
|
// 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)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 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))); |
|
|
|
|
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); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|