DELTASPIKE-636 skip InvocationContext#proceed even with a handled exception
Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/1242cec7 Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/1242cec7 Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/1242cec7 Branch: refs/heads/master Commit: 1242cec7ecd1df68cc184f33c2fda7d2069cbb23 Parents: 7d8ce23 Author: pedroigor <[email protected]> Authored: Thu Jun 12 10:16:31 2014 +0200 Committer: gpetracek <[email protected]> Committed: Thu Jun 12 10:42:18 2014 +0200 ---------------------------------------------------------------------- .../impl/extension/DefaultSecurityStrategy.java | 83 +++++++++++++++++--- 1 file changed, 74 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/deltaspike/blob/1242cec7/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/extension/DefaultSecurityStrategy.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/extension/DefaultSecurityStrategy.java b/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/extension/DefaultSecurityStrategy.java index 2bd9d98..fac5930 100644 --- a/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/extension/DefaultSecurityStrategy.java +++ b/deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/extension/DefaultSecurityStrategy.java @@ -18,7 +18,9 @@ */ package org.apache.deltaspike.security.impl.extension; +import org.apache.deltaspike.core.api.exception.control.event.ExceptionToCatchEvent; import org.apache.deltaspike.core.util.ProxyUtils; +import org.apache.deltaspike.security.api.authorization.AccessDeniedException; import org.apache.deltaspike.security.spi.authorization.SecurityStrategy; import javax.enterprise.context.Dependent; @@ -26,6 +28,7 @@ import javax.enterprise.inject.spi.BeanManager; import javax.inject.Inject; import javax.interceptor.InvocationContext; import java.lang.reflect.Method; +import java.util.Set; /** * {@inheritDoc} @@ -53,24 +56,86 @@ public class DefaultSecurityStrategy implements SecurityStrategy Class targetClass = ProxyUtils.getUnproxiedClass(invocationContext.getTarget().getClass()); //see DELTASPIKE-517 - for (Authorizer authorizer : metaDataStorage.getAuthorizers(targetClass, method)) + Set<Authorizer> authorizers = metaDataStorage.getAuthorizers(targetClass, method); + + Object result = null; + + if (invokeBeforeMethodInvocationAuthorizers(invocationContext, authorizers)) { - if (authorizer.isBeforeMethodInvocationAuthorizer()) + result = invocationContext.proceed(); + + invokeAfterMethodInvocationAuthorizers(invocationContext, authorizers, result); + } + + return result; + } + + private boolean invokeBeforeMethodInvocationAuthorizers(InvocationContext invocationContext, + Set<Authorizer> authorizers) throws IllegalAccessException + { + try + { + for (Authorizer authorizer : authorizers) { - authorizer.authorize(invocationContext, null, this.beanManager); + if (authorizer.isBeforeMethodInvocationAuthorizer()) + { + authorizer.authorize(invocationContext, null, this.beanManager); + } } } + catch (AccessDeniedException ade) + { + return handleAccessDeniedException(ade); + } - Object result = invocationContext.proceed(); + return true; + } - for (Authorizer authorizer : metaDataStorage.getAuthorizers(targetClass, method)) + private boolean invokeAfterMethodInvocationAuthorizers(InvocationContext invocationContext, + Set<Authorizer> authorizers, Object result) throws IllegalAccessException + { + try { - if (authorizer.isAfterMethodInvocationAuthorizer()) + for (Authorizer authorizer : authorizers) { - authorizer.authorize(invocationContext, result, this.beanManager); + if (authorizer.isAfterMethodInvocationAuthorizer()) + { + authorizer.authorize(invocationContext, result, this.beanManager); + } } } - - return result; + catch (AccessDeniedException ade) + { + return handleAccessDeniedException(ade); + } + + return true; + } + + /** + * <p>Fires a {@link org.apache.deltaspike.core.api.exception.control.event.ExceptionToCatchEvent} for the given + * {@link org.apache.deltaspike.security.api.authorization.AccessDeniedException}.</p> + * + * @param ade The previously thrown exception representing a authorization check failure. + * + * @return False if the processing should be aborted. + * + * @throws org.apache.deltaspike.security.api.authorization.AccessDeniedException + * If the exception was not handled by the application. + */ + private boolean handleAccessDeniedException(AccessDeniedException ade) throws AccessDeniedException + { + ExceptionToCatchEvent exceptionToCatchEvent = new ExceptionToCatchEvent(ade); + + exceptionToCatchEvent.setOptional(true); + + beanManager.fireEvent(exceptionToCatchEvent); + + if (!exceptionToCatchEvent.isHandled()) + { + throw ade; + } + + return false; } }
