[seam-commits] Seam SVN: r7440 - in trunk/src/main/org/jboss/seam: security and 1 other directories.
seam-commits at lists.jboss.org
seam-commits at lists.jboss.org
Tue Feb 19 08:31:28 EST 2008
Author: shane.bryzak at jboss.com
Date: 2008-02-19 08:31:28 -0500 (Tue, 19 Feb 2008)
New Revision: 7440
Added:
trunk/src/main/org/jboss/seam/security/DynamicPermissionResolver.java
trunk/src/main/org/jboss/seam/security/PermissionMapper.java
trunk/src/main/org/jboss/seam/security/ResolverChain.java
trunk/src/main/org/jboss/seam/security/RuleBasedPermissionResolver.java
trunk/src/main/org/jboss/seam/security/management/SecurityContext.java
Removed:
trunk/src/main/org/jboss/seam/security/RuleBasedIdentity.java
Modified:
trunk/src/main/org/jboss/seam/el/SeamFunctionMapper.java
trunk/src/main/org/jboss/seam/security/Identity.java
trunk/src/main/org/jboss/seam/security/PermissionCheck.java
trunk/src/main/org/jboss/seam/security/SecurityFunctions.java
trunk/src/main/org/jboss/seam/security/SecurityInterceptor.java
trunk/src/main/org/jboss/seam/security/management/JpaIdentityStore.java
Log:
permission resolver implementation
Modified: trunk/src/main/org/jboss/seam/el/SeamFunctionMapper.java
===================================================================
--- trunk/src/main/org/jboss/seam/el/SeamFunctionMapper.java 2008-02-19 13:07:47 UTC (rev 7439)
+++ trunk/src/main/org/jboss/seam/el/SeamFunctionMapper.java 2008-02-19 13:31:28 UTC (rev 7440)
@@ -1,11 +1,14 @@
package org.jboss.seam.el;
import java.lang.reflect.Method;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import javax.el.FunctionMapper;
+import org.jboss.el.lang.ExtendedFunctionMapper;
import org.jboss.seam.log.LogProvider;
import org.jboss.seam.log.Logging;
import org.jboss.seam.security.SecurityFunctions;
@@ -16,12 +19,12 @@
*
* @author Shane Bryzak
*/
-public class SeamFunctionMapper extends FunctionMapper
+public class SeamFunctionMapper extends ExtendedFunctionMapper
{
- private static Map<String,Method> methodCache = new HashMap<String,Method>();
+ private static Map<String,List<Method>> methodCache = new HashMap<String,List<Method>>();
private static final LogProvider log = Logging.getLogProvider(SeamFunctionMapper.class);
-
+
private FunctionMapper functionMapper;
public SeamFunctionMapper(FunctionMapper functionMapper)
@@ -33,6 +36,8 @@
{
cacheMethod("hasPermission", SecurityFunctions.class, "hasPermission",
new Class[] {String.class, String.class, Object.class});
+ cacheMethod("hasPermission", SecurityFunctions.class, "hasPermission",
+ new Class[] {Object.class, String.class});
cacheMethod("hasRole", SecurityFunctions.class, "hasRole",
new Class[] { String.class });
}
@@ -42,7 +47,8 @@
{
if ( "s".equals(prefix) )
{
- return methodCache.get(localName);
+ List<Method> methods = methodCache.get(localName);
+ return methods != null ? methods.get(0) : null;
}
else if (functionMapper != null)
{
@@ -54,12 +60,50 @@
}
}
+ @Override
+ public Method resolveFunction(String prefix, String localName, int paramCount)
+ {
+ if ( "s".equals(prefix) )
+ {
+ List<Method> methods = methodCache.get(localName);
+ if (methods != null)
+ {
+ for (Method m : methods)
+ {
+ if (m.getParameterTypes().length == paramCount) return m;
+ }
+ }
+
+ return null;
+ }
+ else if (functionMapper != null)
+ {
+ return functionMapper.resolveFunction(prefix, localName);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
private static void cacheMethod(String localName, Class cls, String name, Class[] params)
{
try
{
Method m = cls.getMethod(name, params);
- methodCache.put(localName, m);
+
+ List<Method> methods;
+ if (methodCache.containsKey(localName))
+ {
+ methods = methodCache.get(localName);
+ }
+ else
+ {
+ methods = new ArrayList<Method>();
+ methodCache.put(localName, methods);
+ }
+
+ methods.add(m);
}
catch (NoSuchMethodException ex)
{
Added: trunk/src/main/org/jboss/seam/security/DynamicPermissionResolver.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/DynamicPermissionResolver.java (rev 0)
+++ trunk/src/main/org/jboss/seam/security/DynamicPermissionResolver.java 2008-02-19 13:31:28 UTC (rev 7440)
@@ -0,0 +1,15 @@
+package org.jboss.seam.security;
+
+/**
+ * Resolves permissions dynamically assigned in a peristent store, such as a
+ * database, for example.
+ *
+ * @author Shane Bryzak
+ */
+public class DynamicPermissionResolver implements PermissionResolver
+{
+ public boolean hasPermission(Object target, String action)
+ {
+ return true;
+ }
+}
Modified: trunk/src/main/org/jboss/seam/security/Identity.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/Identity.java 2008-02-19 13:07:47 UTC (rev 7439)
+++ trunk/src/main/org/jboss/seam/security/Identity.java 2008-02-19 13:31:28 UTC (rev 7440)
@@ -25,6 +25,7 @@
import org.jboss.seam.ScopeType;
import org.jboss.seam.Seam;
import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
@@ -90,6 +91,8 @@
private List<String> preAuthenticationRoles = new ArrayList<String>();
+ private PermissionMapper permissionMapper;
+
/**
* Flag that indicates we are in the process of authenticating
*/
@@ -99,6 +102,7 @@
public void create()
{
subject = new Subject();
+ permissionMapper = (PermissionMapper) Component.getInstance(PermissionMapper.class);
}
public static boolean isSecurityEnabled()
@@ -494,6 +498,25 @@
}
}
}
+
+ public void checkPermission(Object target, String action)
+ {
+ isLoggedIn(true);
+
+ if ( !hasPermission(target, action) )
+ {
+ if ( !isLoggedIn() )
+ {
+ if (Events.exists()) Events.instance().raiseEvent(EVENT_NOT_LOGGED_IN);
+ throw new NotLoggedInException();
+ }
+ else
+ {
+ throw new AuthorizationException(String.format(
+ "Authorization check failed for permission[%s,%s]", target, action));
+ }
+ }
+ }
/**
* Performs a permission check for the specified name and action
@@ -505,9 +528,31 @@
*/
public boolean hasPermission(String name, String action, Object...arg)
{
- return !securityEnabled;
+ if (!securityEnabled)
+ {
+ return true;
+ }
+
+ if (arg != null)
+ {
+ return permissionMapper.resolvePermission(arg[0], action);
+ }
+ else
+ {
+ return permissionMapper.resolvePermission(name, action);
+ }
}
+ public boolean hasPermission(Object target, String action)
+ {
+ if (!securityEnabled)
+ {
+ return true;
+ }
+
+ return permissionMapper.resolvePermission(target, action);
+ }
+
/**
* Creates a callback handler that can handle a standard username/password
* callback, using the username and password properties.
@@ -676,7 +721,7 @@
{
if (Strings.isEmpty(restrict.value()))
{
- checkPermission(name, action.toString(), entity);
+ checkPermission(entity, action.toString());
}
else
{
Modified: trunk/src/main/org/jboss/seam/security/PermissionCheck.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/PermissionCheck.java 2008-02-19 13:07:47 UTC (rev 7439)
+++ trunk/src/main/org/jboss/seam/security/PermissionCheck.java 2008-02-19 13:31:28 UTC (rev 7440)
@@ -9,39 +9,54 @@
*/
public class PermissionCheck
{
- private String name;
- private String action;
- private boolean granted;
+ private Object target;
- public PermissionCheck(String name, String action)
- {
- this.name = name;
- this.action = action;
- this.granted = false;
- }
+ @Deprecated
+ private String name;
- public String getName()
- {
- return name;
- }
+ private String action;
+ private boolean granted;
+
+ public PermissionCheck(Object target, String action)
+ {
+ if (target instanceof String)
+ {
+ this.name = (String) target;
+ }
+
+ this.target = target;
+ this.action = action;
+ granted = false;
+ }
+
+ public Object getTarget()
+ {
+ return target;
+ }
- public String getAction()
- {
- return action;
- }
+ @Deprecated
+ public String getName()
+ {
+ return name;
+ }
- public void grant()
- {
- this.granted = true;
- }
-
- public void revoke()
- {
- this.granted = false;
- }
+ public String getAction()
+ {
+ return action;
+ }
- public boolean isGranted()
- {
- return granted;
- }
+ public void grant()
+ {
+ this.granted = true;
+ }
+
+ public void revoke()
+ {
+ this.granted = false;
+ }
+
+ public boolean isGranted()
+ {
+ return granted;
+ }
}
Added: trunk/src/main/org/jboss/seam/security/PermissionMapper.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/PermissionMapper.java (rev 0)
+++ trunk/src/main/org/jboss/seam/security/PermissionMapper.java 2008-02-19 13:31:28 UTC (rev 7440)
@@ -0,0 +1,118 @@
+package org.jboss.seam.security;
+
+import static org.jboss.seam.ScopeType.APPLICATION;
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.Startup;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.core.Init;
+
+/**
+ * Maps permission checks to resolver chains
+ *
+ * @author Shane Bryzak
+ */
+ at Scope(APPLICATION)
+ at Name("org.jboss.seam.security.permissionMapper")
+ at Install(precedence = BUILT_IN)
+ at BypassInterceptors
+ at Startup
+public class PermissionMapper
+{
+ private Map<Class,Map<String,String>> resolverChains = new HashMap<Class,Map<String,String>>();
+
+ private String defaultResolverChain;
+
+ private static final String DEFAULT_RESOLVER_CHAIN = "org.jboss.seam.security.defaultResolverChain";
+
+ private ResolverChain getResolverChain(Object target, String action)
+ {
+ Class targetClass = null;
+
+ if (target instanceof Class)
+ {
+ targetClass = (Class) target;
+ }
+ else
+ {
+ // TODO target may be a component name, or an object, or a view name (or arbitrary name) -
+ // we need to deal with all of these possibilities
+ }
+
+ if (targetClass != null)
+ {
+ Map<String,String> chains = resolverChains.get(target);
+ if (chains != null && chains.containsKey(action))
+ {
+ return (ResolverChain) Component.getInstance(chains.get(action), true);
+ }
+ }
+
+ if (defaultResolverChain != null && !"".equals(defaultResolverChain))
+ {
+ return (ResolverChain) Component.getInstance(defaultResolverChain, true);
+ }
+
+ return createDefaultResolverChain();
+ }
+
+ public boolean resolvePermission(Object target, String action)
+ {
+ ResolverChain chain = getResolverChain(target, action);
+ for (PermissionResolver resolver : chain.getResolvers())
+ {
+ if (resolver.hasPermission(target, action))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private ResolverChain createDefaultResolverChain()
+ {
+ ResolverChain chain = (ResolverChain) Contexts.getSessionContext().get(DEFAULT_RESOLVER_CHAIN);
+
+ if (chain == null)
+ {
+ chain = new ResolverChain();
+
+ for (String resolverName : Init.instance().getPermissionResolvers())
+ {
+ chain.getResolvers().add((PermissionResolver) Component.getInstance(resolverName, true));
+ }
+
+ Contexts.getSessionContext().set(DEFAULT_RESOLVER_CHAIN, chain);
+ }
+
+ return chain;
+ }
+
+ public static PermissionMapper instance()
+ {
+ if ( !Contexts.isApplicationContextActive() )
+ {
+ throw new IllegalStateException("No active application context");
+ }
+
+ PermissionMapper instance = (PermissionMapper) Component.getInstance(
+ PermissionMapper.class, ScopeType.APPLICATION);
+
+ if (instance == null)
+ {
+ throw new IllegalStateException("No PermissionMapper could be created");
+ }
+
+ return instance;
+ }
+}
Added: trunk/src/main/org/jboss/seam/security/ResolverChain.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/ResolverChain.java (rev 0)
+++ trunk/src/main/org/jboss/seam/security/ResolverChain.java 2008-02-19 13:31:28 UTC (rev 7440)
@@ -0,0 +1,26 @@
+package org.jboss.seam.security;
+
+import static org.jboss.seam.ScopeType.SESSION;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+
+ at Scope(SESSION)
+ at BypassInterceptors
+public class ResolverChain
+{
+ private List<PermissionResolver> resolvers = new ArrayList<PermissionResolver>();
+
+ public List<PermissionResolver> getResolvers()
+ {
+ return resolvers;
+ }
+
+ public void setResolvers(List<PermissionResolver> resolvers)
+ {
+ this.resolvers = resolvers;
+ }
+}
Deleted: trunk/src/main/org/jboss/seam/security/RuleBasedIdentity.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/RuleBasedIdentity.java 2008-02-19 13:07:47 UTC (rev 7439)
+++ trunk/src/main/org/jboss/seam/security/RuleBasedIdentity.java 2008-02-19 13:31:28 UTC (rev 7440)
@@ -1,226 +0,0 @@
-package org.jboss.seam.security;
-
-import static org.jboss.seam.ScopeType.SESSION;
-import static org.jboss.seam.annotations.Install.FRAMEWORK;
-
-import java.security.Principal;
-import java.security.acl.Group;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.List;
-
-import org.drools.FactHandle;
-import org.drools.RuleBase;
-import org.drools.StatefulSession;
-import org.drools.base.ClassObjectFilter;
-import org.jboss.seam.Component;
-import org.jboss.seam.annotations.Install;
-import org.jboss.seam.annotations.Name;
-import org.jboss.seam.annotations.Scope;
-import org.jboss.seam.annotations.Startup;
-import org.jboss.seam.annotations.intercept.BypassInterceptors;
-import org.jboss.seam.log.LogProvider;
-import org.jboss.seam.log.Logging;
-
-/**
- * Identity implementation that supports permission
- * checking via a Drools rulebase.
- *
- * @author Shane Bryzak
- *
- */
- at Name("org.jboss.seam.security.identity")
- at Scope(SESSION)
- at BypassInterceptors
- at Install(precedence=FRAMEWORK, classDependencies="org.drools.WorkingMemory")
- at Startup
-public class RuleBasedIdentity extends Identity
-{
- private static final long serialVersionUID = -2798083003251077858L;
-
- public static final String RULES_COMPONENT_NAME = "securityRules";
-
- private static final LogProvider log = Logging.getLogProvider(RuleBasedIdentity.class);
-
- private StatefulSession securityContext;
-
- private RuleBase securityRules;
-
- @Override
- public void create()
- {
- super.create();
- initSecurityContext();
- }
-
- protected void initSecurityContext()
- {
- if (getSecurityRules() == null)
- {
- setSecurityRules((RuleBase) Component.getInstance(RULES_COMPONENT_NAME, true));
- }
-
- if (getSecurityRules() != null)
- {
- setSecurityContext(getSecurityRules().newStatefulSession(false));
- }
-
- if (getSecurityContext() == null)
- {
- log.warn("no security rule base available - please install a RuleBase with the name '" +
- RULES_COMPONENT_NAME + "' if permission checks are required.");
- }
- }
-
- @Override
- protected void postAuthenticate()
- {
- super.postAuthenticate();
-
- if (getSecurityContext() != null)
- {
- getSecurityContext().insert(getPrincipal());
- }
- }
-
- /**
- * Performs a permission check for the specified name and action
- *
- * @param name String The permission name
- * @param action String The permission action
- * @param arg Object Optional object parameter used to make a permission decision
- * @return boolean True if the user has the specified permission
- */
- @Override
- public boolean hasPermission(String name, String action, Object...arg)
- {
- if (!securityEnabled) return true;
-
- StatefulSession securityContext = getSecurityContext();
-
- if (securityContext == null) return false;
-
- List<FactHandle> handles = new ArrayList<FactHandle>();
-
- PermissionCheck check = new PermissionCheck(name, action);
-
- synchronized( securityContext )
- {
- synchronizeContext();
-
- handles.add( securityContext.insert(check) );
-
- for (int i = 0; i < arg.length; i++)
- {
- if (i == 0 && arg[0] instanceof Collection)
- {
- for (Object value : (Collection) arg[i])
- {
- if ( securityContext.getFactHandle(value) == null )
- {
- handles.add( securityContext.insert(value) );
- }
- }
- }
- else
- {
- handles.add( securityContext.insert(arg[i]) );
- }
- }
-
- securityContext.fireAllRules();
-
- for (FactHandle handle : handles)
- securityContext.retract(handle);
- }
-
- return check.isGranted();
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public void unAuthenticate()
- {
- super.unAuthenticate();
- if (getSecurityContext() != null)
- {
- getSecurityContext().dispose();
- setSecurityContext(null);
- }
- initSecurityContext();
- }
-
- /**
- * Synchronizes the state of the security context with that of the subject
- */
- private void synchronizeContext()
- {
- if (getSecurityContext() != null)
- {
- for ( Group sg : getSubject().getPrincipals(Group.class) )
- {
- if ( ROLES_GROUP.equals( sg.getName() ) )
- {
- Enumeration e = sg.members();
- while (e.hasMoreElements())
- {
- Principal role = (Principal) e.nextElement();
-
- boolean found = false;
- Iterator<Role> iter = getSecurityContext().iterateObjects(new ClassObjectFilter(Role.class));
- while (iter.hasNext())
- {
- Role r = iter.next();
- if (r.getName().equals(role.getName()))
- {
- found = true;
- break;
- }
- }
-
- if (!found)
- {
- getSecurityContext().insert(new Role(role.getName()));
- }
-
- }
- }
- }
-
- Iterator<Role> iter = getSecurityContext().iterateObjects(new ClassObjectFilter(Role.class));
- while (iter.hasNext())
- {
- Role r = iter.next();
- if (!super.hasRole(r.getName()))
- {
- FactHandle fh = getSecurityContext().getFactHandle(r);
- getSecurityContext().retract(fh);
- }
- }
- }
- }
-
-
- public StatefulSession getSecurityContext()
- {
- return securityContext;
- }
-
- public void setSecurityContext(StatefulSession securityContext)
- {
- this.securityContext = securityContext;
- }
-
-
- public RuleBase getSecurityRules()
- {
- return securityRules;
- }
-
- public void setSecurityRules(RuleBase securityRules)
- {
- this.securityRules = securityRules;
- }
-}
Added: trunk/src/main/org/jboss/seam/security/RuleBasedPermissionResolver.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/RuleBasedPermissionResolver.java (rev 0)
+++ trunk/src/main/org/jboss/seam/security/RuleBasedPermissionResolver.java 2008-02-19 13:31:28 UTC (rev 7440)
@@ -0,0 +1,248 @@
+package org.jboss.seam.security;
+
+import static org.jboss.seam.ScopeType.SESSION;
+import static org.jboss.seam.annotations.Install.FRAMEWORK;
+
+import java.security.Principal;
+import java.security.acl.Group;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+
+import org.drools.FactHandle;
+import org.drools.RuleBase;
+import org.drools.StatefulSession;
+import org.drools.base.ClassObjectFilter;
+import org.jboss.seam.Component;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.Seam;
+import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Observer;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.Startup;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.log.LogProvider;
+import org.jboss.seam.log.Logging;
+import org.jboss.seam.security.management.JpaIdentityStore;
+import org.jboss.seam.security.management.SecurityContext;
+import org.jboss.seam.security.management.UserAccount;
+
+ at Name("org.jboss.seam.security.ruleBasedPermissionResolver")
+ at Scope(SESSION)
+ at BypassInterceptors
+ at Install(precedence=FRAMEWORK, classDependencies="org.drools.WorkingMemory")
+ at Startup
+public class RuleBasedPermissionResolver implements PermissionResolver
+{
+ public static final String RULES_COMPONENT_NAME = "securityRules";
+
+ private static final LogProvider log = Logging.getLogProvider(RuleBasedPermissionResolver.class);
+
+ private StatefulSession securityContext;
+
+ private RuleBase securityRules;
+
+ @Create
+ public boolean create()
+ {
+ initSecurityContext();
+ return getSecurityContext() != null;
+ }
+
+ protected void initSecurityContext()
+ {
+ if (getSecurityRules() == null)
+ {
+ setSecurityRules((RuleBase) Component.getInstance(RULES_COMPONENT_NAME, true));
+ }
+
+ if (getSecurityRules() != null)
+ {
+ setSecurityContext(getSecurityRules().newStatefulSession(false));
+ }
+
+ if (getSecurityContext() == null)
+ {
+ log.warn("no security rule base available - please install a RuleBase with the name '" +
+ RULES_COMPONENT_NAME + "' if permission checks are required.");
+ }
+ }
+
+ @Observer(Identity.EVENT_POST_AUTHENTICATE)
+ public void postAuthenticate()
+ {
+ if (getSecurityContext() != null)
+ {
+ getSecurityContext().insert(Identity.instance().getPrincipal());
+ }
+ }
+
+ /**
+ * Performs a permission check for the specified name and action
+ *
+ * @param target Object The target of the permission check
+ * @param action String The action to be performed on the target
+ * @return boolean True if the user has the specified permission
+ */
+ public boolean hasPermission(Object target, String action)
+ {
+ StatefulSession securityContext = getSecurityContext();
+
+ if (securityContext == null) return false;
+
+ List<FactHandle> handles = new ArrayList<FactHandle>();
+
+ if (!(target instanceof String) && !(target instanceof Class))
+ {
+ handles.add( securityContext.insert(target) );
+ }
+
+ if (target instanceof Class)
+ {
+ String componentName = Seam.getComponentName((Class) target);
+ target = componentName != null ? componentName : ((Class) target).getName();
+ }
+
+ PermissionCheck check = new PermissionCheck(target, action);
+
+ synchronized( securityContext )
+ {
+ synchronizeContext();
+
+ handles.add( securityContext.insert(check) );
+
+ securityContext.fireAllRules();
+
+ for (FactHandle handle : handles)
+ securityContext.retract(handle);
+ }
+
+ return check.isGranted();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Observer(Identity.EVENT_LOGGED_OUT)
+ public void unAuthenticate()
+ {
+ if (getSecurityContext() != null)
+ {
+ getSecurityContext().dispose();
+ setSecurityContext(null);
+ }
+ initSecurityContext();
+ }
+
+ /**
+ * Synchronises the state of the security context with that of the subject
+ */
+ private void synchronizeContext()
+ {
+ Identity identity = Identity.instance();
+
+ getSecurityContext().insert(identity.getPrincipal());
+
+ if (getSecurityContext() != null)
+ {
+ for ( Group sg : identity.getSubject().getPrincipals(Group.class) )
+ {
+ if ( Identity.ROLES_GROUP.equals( sg.getName() ) )
+ {
+ Enumeration e = sg.members();
+ while (e.hasMoreElements())
+ {
+ Principal role = (Principal) e.nextElement();
+
+ boolean found = false;
+ Iterator<Role> iter = getSecurityContext().iterateObjects(new ClassObjectFilter(Role.class));
+ while (iter.hasNext())
+ {
+ Role r = iter.next();
+ if (r.getName().equals(role.getName()))
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ getSecurityContext().insert(new Role(role.getName()));
+ }
+
+ }
+ }
+ }
+
+ Iterator<Role> iter = getSecurityContext().iterateObjects(new ClassObjectFilter(Role.class));
+ while (iter.hasNext())
+ {
+ Role r = iter.next();
+ if (!identity.hasRole(r.getName()))
+ {
+ FactHandle fh = getSecurityContext().getFactHandle(r);
+ getSecurityContext().retract(fh);
+ }
+ }
+ }
+ }
+
+
+ public StatefulSession getSecurityContext()
+ {
+ return securityContext;
+ }
+
+ public void setSecurityContext(StatefulSession securityContext)
+ {
+ this.securityContext = securityContext;
+ }
+
+
+ public RuleBase getSecurityRules()
+ {
+ return securityRules;
+ }
+
+ public void setSecurityRules(RuleBase securityRules)
+ {
+ this.securityRules = securityRules;
+ }
+
+ public static RuleBasedPermissionResolver instance()
+ {
+ if ( !Contexts.isSessionContextActive() )
+ {
+ throw new IllegalStateException("No active session context");
+ }
+
+ RuleBasedPermissionResolver instance = (RuleBasedPermissionResolver) Component.getInstance(
+ RuleBasedPermissionResolver.class, ScopeType.SESSION);
+
+ if (instance == null)
+ {
+ throw new IllegalStateException("No RuleBasedPermissionResolver could be created");
+ }
+
+ return instance;
+ }
+
+ /**
+ * If we were authenticated with the JpaIdentityStore, then insert the authenticated
+ * UserAccount into the security context.
+ */
+ @Observer(Identity.EVENT_POST_AUTHENTICATE)
+ public void setUserAccountInSecurityContext()
+ {
+ if (Contexts.isEventContextActive() && Contexts.isSessionContextActive() &&
+ Contexts.getEventContext().isSet(JpaIdentityStore.AUTHENTICATED_USER))
+ {
+ SecurityContext context = new SecurityContext();
+ context.setUserAccount((UserAccount) Contexts.getEventContext().get(JpaIdentityStore.AUTHENTICATED_USER));
+ getSecurityContext().insert(context);
+ }
+ }
+}
Modified: trunk/src/main/org/jboss/seam/security/SecurityFunctions.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/SecurityFunctions.java 2008-02-19 13:07:47 UTC (rev 7439)
+++ trunk/src/main/org/jboss/seam/security/SecurityFunctions.java 2008-02-19 13:31:28 UTC (rev 7440)
@@ -23,4 +23,9 @@
return Identity.instance().hasPermission(name, action);
}
}
+
+ public static boolean hasPermission(Object target, String action)
+ {
+ return Identity.instance().hasPermission(target, action);
+ }
}
Modified: trunk/src/main/org/jboss/seam/security/SecurityInterceptor.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/SecurityInterceptor.java 2008-02-19 13:07:47 UTC (rev 7439)
+++ trunk/src/main/org/jboss/seam/security/SecurityInterceptor.java 2008-02-19 13:31:28 UTC (rev 7440)
@@ -60,7 +60,7 @@
}
else if (target != null && action != null)
{
- // TODO implement the security check
+ Identity.instance().checkPermission(target, action);
}
}
}
@@ -162,7 +162,7 @@
*/
private String createDefaultExpr(Method method)
{
- return String.format( "#{s:hasPermission('%s','%s', null)}",
+ return String.format( "#{s:hasPermission('%s','%s')}",
getComponent().getName(), method.getName() );
}
}
Modified: trunk/src/main/org/jboss/seam/security/management/JpaIdentityStore.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/management/JpaIdentityStore.java 2008-02-19 13:07:47 UTC (rev 7439)
+++ trunk/src/main/org/jboss/seam/security/management/JpaIdentityStore.java 2008-02-19 13:31:28 UTC (rev 7440)
@@ -15,9 +15,12 @@
import org.jboss.seam.Component;
import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.Observer;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.core.Events;
+import org.jboss.seam.security.Identity;
import org.jboss.seam.security.management.UserAccount.AccountType;
import org.jboss.seam.util.Hex;
@@ -30,6 +33,8 @@
@BypassInterceptors
public class JpaIdentityStore implements IdentityStore
{
+ public static final String AUTHENTICATED_USER = "org.jboss.seam.security.management.authenticatedUser";
+
public static final String EVENT_ACCOUNT_CREATED = "org.jboss.seam.security.management.accountCreated";
public static final String EVENT_ACCOUNT_AUTHENTICATED = "org.jboss.seam.security.management.accountAuthenticated";
@@ -355,15 +360,30 @@
}
boolean success = hashPassword(password, username).equals(account.getPasswordHash());
-
+
if (success && Events.exists())
{
+ if (Contexts.isEventContextActive())
+ {
+ Contexts.getEventContext().set(AUTHENTICATED_USER, account);
+ }
+
Events.instance().raiseEvent(EVENT_ACCOUNT_AUTHENTICATED, account);
}
return success;
}
+ @Observer(Identity.EVENT_POST_AUTHENTICATE)
+ public void setUserAccountForSession()
+ {
+ if (Contexts.isEventContextActive() && Contexts.isSessionContextActive())
+ {
+ Contexts.getSessionContext().set(AUTHENTICATED_USER,
+ Contexts.getEventContext().get(AUTHENTICATED_USER));
+ }
+ }
+
protected UserAccount validateAccount(String name)
{
try
Added: trunk/src/main/org/jboss/seam/security/management/SecurityContext.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/management/SecurityContext.java (rev 0)
+++ trunk/src/main/org/jboss/seam/security/management/SecurityContext.java 2008-02-19 13:31:28 UTC (rev 7440)
@@ -0,0 +1,21 @@
+package org.jboss.seam.security.management;
+
+/**
+ * A wrapper that is inserted into the working memory for rule-based permissions.
+ *
+ * @author Shane Bryzak
+ */
+public class SecurityContext
+{
+ private UserAccount userAccount;
+
+ public UserAccount getUserAccount()
+ {
+ return userAccount;
+ }
+
+ public void setUserAccount(UserAccount userAccount)
+ {
+ this.userAccount = userAccount;
+ }
+}
More information about the seam-commits
mailing list