You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by gp...@apache.org on 2012/02/02 15:12:29 UTC
svn commit: r1239633 - in /myfaces/extensions/cdi/trunk:
core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/security/
core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/security/spi/
core/impl/src/main/java/org/apache/my...
Author: gpetracek
Date: Thu Feb 2 14:12:28 2012
New Revision: 1239633
URL: http://svn.apache.org/viewvc?rev=1239633&view=rev
Log:
EXTCDI-261 EXTCDI-262 @Secured for stereotypes and support of custom meta-data
Modified:
myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/security/AccessDecisionVoterContext.java
myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/security/Secured.java
myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/security/spi/EditableAccessDecisionVoterContext.java
myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/util/SecurityUtils.java
myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/DefaultAccessDecisionVoterStateContext.java
myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/DefaultSecurityStrategy.java
myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/SecurityAwareViewHandler.java
myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/SecurityViewListener.java
Modified: myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/security/AccessDecisionVoterContext.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/security/AccessDecisionVoterContext.java?rev=1239633&r1=1239632&r2=1239633&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/security/AccessDecisionVoterContext.java (original)
+++ myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/security/AccessDecisionVoterContext.java Thu Feb 2 14:12:28 2012
@@ -20,6 +20,7 @@ package org.apache.myfaces.extensions.cd
import java.io.Serializable;
import java.util.List;
+import java.util.Map;
/**
* Optional context which allows to get the current state as well as the results of the security check.
@@ -38,4 +39,19 @@ public interface AccessDecisionVoterCont
* @return found violations
*/
List<SecurityViolation> getViolations();
+
+ /**
+ * Exposes the found meta-data
+ * @return found meta-data
+ */
+ Map<String, Object> getMetaData();
+
+ /**
+ * Exposes meta-data for the given key
+ * @param key meta-data key
+ * @param targetType target type
+ * @param <T> target type
+ * @return meta-data for the given key or null if there is no value for the given key
+ */
+ <T> T getMetaDataFor(String key, Class<T> targetType);
}
Modified: myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/security/Secured.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/security/Secured.java?rev=1239633&r1=1239632&r2=1239633&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/security/Secured.java (original)
+++ myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/security/Secured.java Thu Feb 2 14:12:28 2012
@@ -29,12 +29,13 @@ import java.lang.annotation.Documented;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
/**
* Interceptor for securing beans.
* It's also possible to use it as meta-annotation for type-safe view-configs.
*/
-@Target({TYPE, METHOD})
+@Target({TYPE, METHOD, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Documented
Modified: myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/security/spi/EditableAccessDecisionVoterContext.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/security/spi/EditableAccessDecisionVoterContext.java?rev=1239633&r1=1239632&r2=1239633&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/security/spi/EditableAccessDecisionVoterContext.java (original)
+++ myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/security/spi/EditableAccessDecisionVoterContext.java Thu Feb 2 14:12:28 2012
@@ -28,6 +28,14 @@ import org.apache.myfaces.extensions.cdi
public interface EditableAccessDecisionVoterContext extends AccessDecisionVoterContext
{
/**
+ * Allows to add custom meta-data. The default security strategy adds custom annotations of the intercepted method
+ * as well as class-level annotations. (Currently inherited annotations aren't supported)
+ * @param key key for the meta-data
+ * @param metaData meta-data which should be added
+ */
+ void addMetaData(String key, Object metaData);
+
+ /**
* Updates the state of the context
* @param accessDecisionVoterState current state
*/
Modified: myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/util/SecurityUtils.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/util/SecurityUtils.java?rev=1239633&r1=1239632&r2=1239633&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/util/SecurityUtils.java (original)
+++ myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/util/SecurityUtils.java Thu Feb 2 14:12:28 2012
@@ -50,11 +50,13 @@ public abstract class SecurityUtils
* Helper for invoking the given {@link AccessDecisionVoter}s
* @param invocationContext current invocation-context (might be null in case of secured views)
* @param beanManager current bean-manager
+ * @param voterContext current access-decision-voter-context
* @param accessDecisionVoters current access-decision-voters
* @param errorView optional inline error view
*/
public static void invokeVoters(InvocationContext invocationContext,
BeanManager beanManager,
+ AccessDecisionVoterContext voterContext,
List<Class<? extends AccessDecisionVoter>> accessDecisionVoters,
Class<? extends ViewConfig> errorView)
{
@@ -63,9 +65,6 @@ public abstract class SecurityUtils
return;
}
- AccessDecisionVoterContext voterContext =
- CodiUtils.getContextualReferenceByClass(beanManager, AccessDecisionVoterContext.class, true);
-
AccessDecisionState voterState = AccessDecisionState.VOTE_IN_PROGRESS;
try
{
Modified: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/DefaultAccessDecisionVoterStateContext.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/DefaultAccessDecisionVoterStateContext.java?rev=1239633&r1=1239632&r2=1239633&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/DefaultAccessDecisionVoterStateContext.java (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/DefaultAccessDecisionVoterStateContext.java Thu Feb 2 14:12:28 2012
@@ -25,7 +25,9 @@ import org.apache.myfaces.extensions.cdi
import javax.enterprise.context.RequestScoped;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* {@inheritDoc}
@@ -39,6 +41,8 @@ public class DefaultAccessDecisionVoterS
private List<SecurityViolation> securityViolations;
+ private Map<String, Object> metaData = new HashMap<String, Object>();
+
/**
* {@inheritDoc}
*/
@@ -62,13 +66,45 @@ public class DefaultAccessDecisionVoterS
/**
* {@inheritDoc}
*/
+ public Map<String, Object> getMetaData()
+ {
+ return Collections.unmodifiableMap(this.metaData);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public <T> T getMetaDataFor(String key, Class<T> targetType)
+ {
+ return (T)this.metaData.get(key);
+ }
+
+ public void addMetaData(String key, Object metaData)
+ {
+ //TODO specify nested security calls
+ this.metaData.put(key, metaData);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public void setState(AccessDecisionState accessDecisionVoterState)
{
if(AccessDecisionState.VOTE_IN_PROGRESS.equals(accessDecisionVoterState))
{
this.securityViolations = new ArrayList<SecurityViolation>(); //lazy init
}
+
this.state = accessDecisionVoterState;
+
+ if(AccessDecisionState.INITIAL.equals(accessDecisionVoterState) ||
+ AccessDecisionState.VOTE_IN_PROGRESS.equals(accessDecisionVoterState))
+ {
+ return;
+ }
+
+ //meta-data is only needed until the end of a voting process
+ this.metaData.clear();
}
/**
Modified: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/DefaultSecurityStrategy.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/DefaultSecurityStrategy.java?rev=1239633&r1=1239632&r2=1239633&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/DefaultSecurityStrategy.java (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/DefaultSecurityStrategy.java Thu Feb 2 14:12:28 2012
@@ -18,6 +18,9 @@
*/
package org.apache.myfaces.extensions.cdi.jsf.impl.security;
+import org.apache.myfaces.extensions.cdi.core.api.security.AccessDecisionVoterContext;
+import org.apache.myfaces.extensions.cdi.core.impl.security.spi.EditableAccessDecisionVoterContext;
+import org.apache.myfaces.extensions.cdi.core.impl.util.CodiUtils;
import org.apache.myfaces.extensions.cdi.jsf.impl.security.spi.SecurityStrategy;
import org.apache.myfaces.extensions.cdi.core.api.security.Secured;
import org.apache.myfaces.extensions.cdi.core.api.security.AccessDecisionVoter;
@@ -27,8 +30,11 @@ import javax.inject.Inject;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.context.Dependent;
import javax.interceptor.InvocationContext;
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
import java.util.Arrays;
import java.lang.reflect.Method;
+import java.util.List;
/**
* {@inheritDoc}
@@ -47,29 +53,66 @@ public class DefaultSecurityStrategy imp
*/
public Object execute(InvocationContext invocationContext) throws Exception
{
- Secured secured = getSecuredAnnotation(invocationContext);
+ AccessDecisionVoterContext voterContext =
+ CodiUtils.getContextualReferenceByClass(beanManager, AccessDecisionVoterContext.class, true);
- Class<? extends AccessDecisionVoter>[] voterClasses = secured.value();
+ Secured secured = null;
- invokeVoters(invocationContext, this.beanManager, Arrays.asList(voterClasses), secured.errorView());
+ List<Annotation> annotatedTypeMetadata = extractMetadata(invocationContext);
+
+ for (Annotation annotation : annotatedTypeMetadata)
+ {
+ if(Secured.class.isAssignableFrom(annotation.annotationType()))
+ {
+ secured = (Secured)annotation;
+ }
+ else if(voterContext instanceof EditableAccessDecisionVoterContext)
+ {
+ ((EditableAccessDecisionVoterContext)voterContext)
+ .addMetaData(annotation.annotationType().getName(), annotation);
+ }
+ }
+
+ if(secured != null)
+ {
+ Class<? extends AccessDecisionVoter>[] voterClasses = secured.value();
+
+ invokeVoters(invocationContext, this.beanManager, voterContext,
+ Arrays.asList(voterClasses), secured.errorView());
+ }
return invocationContext.proceed();
}
- //TODO refactor it to a generic impl. and move it to an util class
- private Secured getSecuredAnnotation(InvocationContext invocationContext)
+ private List<Annotation> extractMetadata(InvocationContext invocationContext)
{
- Secured secured;
+ List<Annotation> result = new ArrayList<Annotation>();
+
Method method = invocationContext.getMethod();
- if(method.isAnnotationPresent(Secured.class))
- {
- secured = method.getAnnotation(Secured.class);
- }
- else
+ result.addAll(getAllAnnotations(method.getAnnotations()));
+ result.addAll(getAllAnnotations(method.getDeclaringClass().getAnnotations()));
+
+ return result;
+ }
+
+ private List<Annotation> getAllAnnotations(Annotation[] annotations)
+ {
+ List<Annotation> result = new ArrayList<Annotation>();
+
+ String annotationName;
+ for(Annotation annotation : annotations)
{
- secured = method.getDeclaringClass().getAnnotation(Secured.class);
+ annotationName = annotation.annotationType().getName();
+ if(annotationName.startsWith("java.") || annotationName.startsWith("javax."))
+ {
+ continue;
+ }
+
+ result.add(annotation);
+ result.addAll(getAllAnnotations(annotation.annotationType().getAnnotations()));
}
- return secured;
+
+ return result;
}
}
Modified: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/SecurityAwareViewHandler.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/SecurityAwareViewHandler.java?rev=1239633&r1=1239632&r2=1239633&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/SecurityAwareViewHandler.java (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/SecurityAwareViewHandler.java Thu Feb 2 14:12:28 2012
@@ -21,8 +21,10 @@ package org.apache.myfaces.extensions.cd
import org.apache.myfaces.extensions.cdi.core.api.activation.Deactivatable;
import org.apache.myfaces.extensions.cdi.core.api.config.view.ViewConfig;
import org.apache.myfaces.extensions.cdi.core.api.provider.BeanManagerProvider;
+import org.apache.myfaces.extensions.cdi.core.api.security.AccessDecisionVoterContext;
import org.apache.myfaces.extensions.cdi.core.api.security.AccessDeniedException;
import org.apache.myfaces.extensions.cdi.core.impl.util.ClassDeactivation;
+import org.apache.myfaces.extensions.cdi.core.impl.util.CodiUtils;
import org.apache.myfaces.extensions.cdi.jsf.api.config.view.ViewConfigDescriptor;
import org.apache.myfaces.extensions.cdi.jsf.impl.config.view.ViewConfigCache;
import org.apache.myfaces.extensions.cdi.jsf.impl.config.view.spi.EditableViewConfigDescriptor;
@@ -92,6 +94,9 @@ public class SecurityAwareViewHandler ex
{
lazyInit();
+ AccessDecisionVoterContext voterContext =
+ CodiUtils.getContextualReferenceByClass(beanManager, AccessDecisionVoterContext.class, true);
+
Class<? extends ViewConfig> errorView = null;
if(entry instanceof EditableViewConfigDescriptor)
@@ -99,7 +104,7 @@ public class SecurityAwareViewHandler ex
errorView = ((EditableViewConfigDescriptor)entry).getErrorView();
}
- invokeVoters(null /*TODO*/, this.beanManager, entry.getAccessDecisionVoters(), errorView);
+ invokeVoters(null /*TODO*/, this.beanManager, voterContext, entry.getAccessDecisionVoters(), errorView);
}
}
catch (AccessDeniedException accessDeniedException)
Modified: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/SecurityViewListener.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/SecurityViewListener.java?rev=1239633&r1=1239632&r2=1239633&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/SecurityViewListener.java (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/jsf/impl/security/SecurityViewListener.java Thu Feb 2 14:12:28 2012
@@ -19,6 +19,8 @@
package org.apache.myfaces.extensions.cdi.jsf.impl.security;
import org.apache.myfaces.extensions.cdi.core.api.config.view.ViewConfig;
+import org.apache.myfaces.extensions.cdi.core.api.security.AccessDecisionVoterContext;
+import org.apache.myfaces.extensions.cdi.core.impl.util.CodiUtils;
import org.apache.myfaces.extensions.cdi.jsf.api.listener.phase.AfterPhase;
import org.apache.myfaces.extensions.cdi.jsf.api.listener.phase.BeforePhase;
import static org.apache.myfaces.extensions.cdi.jsf.api.listener.phase.JsfPhaseId.*;
@@ -102,11 +104,14 @@ public class SecurityViewListener
{
Class<? extends ViewConfig> errorView = null;
+ AccessDecisionVoterContext voterContext =
+ CodiUtils.getContextualReferenceByClass(beanManager, AccessDecisionVoterContext.class, true);
+
if(entry instanceof EditableViewConfigDescriptor)
{
errorView = ((EditableViewConfigDescriptor)entry).getErrorView();
}
- invokeVoters(null, beanManager, entry.getAccessDecisionVoters(), errorView);
+ invokeVoters(null, beanManager, voterContext, entry.getAccessDecisionVoters(), errorView);
}
catch (AccessDeniedException accessDeniedException)
{