[seam-commits] Seam SVN: r12453 - modules/security/trunk/impl/src/main/java/org/jboss/seam/security.
seam-commits at lists.jboss.org
seam-commits at lists.jboss.org
Tue Apr 13 06:40:41 EDT 2010
Author: shane.bryzak at jboss.com
Date: 2010-04-13 06:40:40 -0400 (Tue, 13 Apr 2010)
New Revision: 12453
Added:
modules/security/trunk/impl/src/main/java/org/jboss/seam/security/Authenticator.java
modules/security/trunk/impl/src/main/java/org/jboss/seam/security/AuthorizationException.java
modules/security/trunk/impl/src/main/java/org/jboss/seam/security/Credentials.java
modules/security/trunk/impl/src/main/java/org/jboss/seam/security/EntityAction.java
modules/security/trunk/impl/src/main/java/org/jboss/seam/security/EntityPermissionChecker.java
modules/security/trunk/impl/src/main/java/org/jboss/seam/security/EntitySecurityListener.java
modules/security/trunk/impl/src/main/java/org/jboss/seam/security/HibernateSecurityInterceptor.java
modules/security/trunk/impl/src/main/java/org/jboss/seam/security/JaasConfiguration.java
modules/security/trunk/impl/src/main/java/org/jboss/seam/security/JpaTokenStore.java
modules/security/trunk/impl/src/main/java/org/jboss/seam/security/NotLoggedInException.java
modules/security/trunk/impl/src/main/java/org/jboss/seam/security/RememberMe.java
modules/security/trunk/impl/src/main/java/org/jboss/seam/security/RequestSecurityState.java
modules/security/trunk/impl/src/main/java/org/jboss/seam/security/Role.java
modules/security/trunk/impl/src/main/java/org/jboss/seam/security/RunAsOperation.java
modules/security/trunk/impl/src/main/java/org/jboss/seam/security/Secure.java
modules/security/trunk/impl/src/main/java/org/jboss/seam/security/SecurityEventMessages.java
modules/security/trunk/impl/src/main/java/org/jboss/seam/security/SecurityException.java
modules/security/trunk/impl/src/main/java/org/jboss/seam/security/SecurityInterceptor.java
modules/security/trunk/impl/src/main/java/org/jboss/seam/security/SimpleGroup.java
modules/security/trunk/impl/src/main/java/org/jboss/seam/security/SimplePrincipal.java
modules/security/trunk/impl/src/main/java/org/jboss/seam/security/TokenStore.java
Log:
added classes
Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/Authenticator.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/Authenticator.java (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/Authenticator.java 2010-04-13 10:40:40 UTC (rev 12453)
@@ -0,0 +1,11 @@
+package org.jboss.seam.security;
+
+/**
+ * Authenticator bean type
+ *
+ * @author Shane Bryzak
+ */
+public interface Authenticator
+{
+ boolean authenticate();
+}
Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/AuthorizationException.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/AuthorizationException.java (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/AuthorizationException.java 2010-04-13 10:40:40 UTC (rev 12453)
@@ -0,0 +1,16 @@
+package org.jboss.seam.security;
+
+/**
+ * Thrown when an authenticated user has insufficient rights to carry out an action.
+ *
+ * @author Shane Bryzak
+ */
+public class AuthorizationException extends SecurityException
+{
+ private static final long serialVersionUID = -981091398588455903L;
+
+ public AuthorizationException(String message)
+ {
+ super(message);
+ }
+}
Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/Credentials.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/Credentials.java (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/Credentials.java 2010-04-13 10:40:40 UTC (rev 12453)
@@ -0,0 +1,103 @@
+package org.jboss.seam.security;
+
+import java.io.Serializable;
+
+import javax.enterprise.context.SessionScoped;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.jboss.seam.security.events.CredentialsInitializedEvent;
+import org.jboss.seam.security.events.CredentialsUpdatedEvent;
+
+ at Named//("org.jboss.seam.security.credentials")
+ at SessionScoped
+public class Credentials implements Serializable
+{
+ private static final long serialVersionUID = -2271248957776488426L;
+
+ @Inject BeanManager manager;
+
+ private String username;
+ private String password;
+
+ private boolean invalid;
+
+ private boolean initialized;
+
+ public Credentials() {}
+
+ public boolean isInitialized()
+ {
+ return initialized;
+ }
+
+ public void setInitialized(boolean initialized)
+ {
+ this.initialized = initialized;
+ }
+
+ public String getUsername()
+ {
+ if (!isInitialized())
+ {
+ setInitialized(true);
+ manager.fireEvent(new CredentialsInitializedEvent(this));
+ }
+
+ return username;
+ }
+
+ public void setUsername(String username)
+ {
+ if (this.username != username && (this.username == null || !this.username.equals(username)))
+ {
+ this.username = username;
+ invalid = false;
+ manager.fireEvent(new CredentialsUpdatedEvent());
+ }
+ }
+
+ public String getPassword()
+ {
+ return password;
+ }
+
+ public void setPassword(String password)
+ {
+ if (this.password != password && (this.password == null || !this.password.equals(password)))
+ {
+ this.password = password;
+ invalid = false;
+ manager.fireEvent(new CredentialsUpdatedEvent());
+ }
+ }
+
+ public boolean isSet()
+ {
+ return getUsername() != null && password != null;
+ }
+
+ public boolean isInvalid()
+ {
+ return invalid;
+ }
+
+ public void invalidate()
+ {
+ invalid = true;
+ }
+
+ public void clear()
+ {
+ username = null;
+ password = null;
+ initialized = false;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "Credentials[" + username + "]";
+ }
+}
Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/EntityAction.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/EntityAction.java (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/EntityAction.java 2010-04-13 10:40:40 UTC (rev 12453)
@@ -0,0 +1,23 @@
+package org.jboss.seam.security;
+
+/**
+ * Actions that may be performed upon entities
+ * in JPA or Hibernate.
+ *
+ * @author Shane Bryzak
+ *
+ */
+public enum EntityAction {
+
+ READ,
+ INSERT,
+ UPDATE,
+ DELETE;
+
+ @Override
+ public String toString()
+ {
+ return super.name().toLowerCase();
+ }
+
+}
\ No newline at end of file
Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/EntityPermissionChecker.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/EntityPermissionChecker.java (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/EntityPermissionChecker.java 2010-04-13 10:40:40 UTC (rev 12453)
@@ -0,0 +1,87 @@
+package org.jboss.seam.security;
+
+import javax.enterprise.context.ApplicationScoped;
+
+/**
+ * Entity permission checks
+ *
+ * @author Shane Bryzak
+ */
+ at ApplicationScoped
+public class EntityPermissionChecker
+{
+ /*
+ private String entityManagerName = "entityManager";
+
+ @Current Manager manager;
+
+ private EntityManager getEntityManager()
+ {
+ return (EntityManager) Component.getInstance(entityManagerName);
+ }
+
+ public String getEntityManagerName()
+ {
+ return entityManagerName;
+ }
+
+ public void setEntityManagerName(String name)
+ {
+ this.entityManagerName = name;
+ }
+
+ public void checkEntityPermission(Object entity, EntityAction action)
+ {
+ if (!Identity.isSecurityEnabled()) return;
+
+ Identity identity = manager.getInstanceByType(Identity.class);
+ identity.tryLogin();
+
+ PersistenceProvider provider = manager.getInstanceByType(PersistenceProvider.class);
+
+ Class beanClass = provider.getBeanClass(entity);
+
+ if (beanClass != null)
+ {
+ Method m = null;
+ switch (action)
+ {
+ case READ:
+ m = provider.getPostLoadMethod(entity, getEntityManager());
+ break;
+ case INSERT:
+ m = provider.getPrePersistMethod(entity, getEntityManager());
+ break;
+ case UPDATE:
+ m = provider.getPreUpdateMethod(entity, getEntityManager());
+ break;
+ case DELETE:
+ m = provider.getPreRemoveMethod(entity, getEntityManager());
+ }
+
+ Restrict restrict = null;
+
+ if (m != null && m.isAnnotationPresent(Restrict.class))
+ {
+ restrict = m.getAnnotation(Restrict.class);
+ }
+ else if (entity.getClass().isAnnotationPresent(Restrict.class))
+ {
+ restrict = entity.getClass().getAnnotation(Restrict.class);
+ }
+
+ if (restrict != null)
+ {
+ if (Strings.isEmpty(restrict.value()))
+ {
+ identity.checkPermission(entity, action.toString());
+ }
+ else
+ {
+ identity.checkRestriction(restrict.value());
+ }
+ }
+ }
+ }
+ */
+}
Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/EntitySecurityListener.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/EntitySecurityListener.java (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/EntitySecurityListener.java 2010-04-13 10:40:40 UTC (rev 12453)
@@ -0,0 +1,46 @@
+package org.jboss.seam.security;
+
+import static org.jboss.seam.security.EntityAction.DELETE;
+import static org.jboss.seam.security.EntityAction.INSERT;
+import static org.jboss.seam.security.EntityAction.READ;
+import static org.jboss.seam.security.EntityAction.UPDATE;
+
+import javax.persistence.PostLoad;
+import javax.persistence.PrePersist;
+import javax.persistence.PreRemove;
+import javax.persistence.PreUpdate;
+
+
+/**
+ * Facilitates security checks for entity beans.
+ *
+ * @author Shane Bryzak
+ */
+public class EntitySecurityListener
+{
+ /*
+ @PostLoad
+ public void postLoad(Object entity)
+ {
+ EntityPermissionChecker.instance().checkEntityPermission(entity, READ);
+ }
+
+ @PrePersist
+ public void prePersist(Object entity)
+ {
+ EntityPermissionChecker.instance().checkEntityPermission(entity, INSERT);
+ }
+
+ @PreUpdate
+ public void preUpdate(Object entity)
+ {
+ EntityPermissionChecker.instance().checkEntityPermission(entity, UPDATE);
+ }
+
+ @PreRemove
+ public void preRemove(Object entity)
+ {
+ EntityPermissionChecker.instance().checkEntityPermission(entity, DELETE);
+ }
+ */
+}
Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/HibernateSecurityInterceptor.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/HibernateSecurityInterceptor.java (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/HibernateSecurityInterceptor.java 2010-04-13 10:40:40 UTC (rev 12453)
@@ -0,0 +1,102 @@
+package org.jboss.seam.security;
+
+import static org.jboss.seam.security.EntityAction.DELETE;
+import static org.jboss.seam.security.EntityAction.INSERT;
+import static org.jboss.seam.security.EntityAction.READ;
+import static org.jboss.seam.security.EntityAction.UPDATE;
+
+import java.io.Serializable;
+
+import org.hibernate.EmptyInterceptor;
+import org.hibernate.Interceptor;
+import org.hibernate.type.Type;
+//import org.jboss.seam.Entity.NotEntityException;
+
+/**
+ * Facilitates security checks for Hibernate entities
+ *
+ * @author Shane Bryzak
+ *
+ */
+public class HibernateSecurityInterceptor extends EmptyInterceptor
+{
+ /*
+ private Interceptor wrappedInterceptor;
+
+ public HibernateSecurityInterceptor(Interceptor wrappedInterceptor)
+ {
+ this.wrappedInterceptor = wrappedInterceptor;
+ }
+
+ @Override
+ public boolean onLoad(Object entity, Serializable id, Object[] state,
+ String[] propertyNames, Type[] types)
+ {
+ try
+ {
+ EntityPermissionChecker.instance().checkEntityPermission(entity, READ);
+ }
+ catch (NotEntityException e)
+ {
+ // Not a JPA entity
+ }
+
+ return wrappedInterceptor != null ?
+ wrappedInterceptor.onLoad(entity, id, state, propertyNames, types) :
+ false;
+ }
+
+ @Override
+ public void onDelete(Object entity, Serializable id, Object[] state,
+ String[] propertyNames, Type[] types)
+ {
+ try
+ {
+ EntityPermissionChecker.instance().checkEntityPermission(entity, DELETE);
+ }
+ catch (NotEntityException e)
+ {
+ // Not a JPA entity
+ }
+
+ if (wrappedInterceptor != null)
+ wrappedInterceptor.onDelete(entity, id, state, propertyNames, types);
+ }
+
+ @Override
+ public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState,
+ Object[] previousState, String[] propertyNames, Type[] types)
+ {
+ try
+ {
+ EntityPermissionChecker.instance().checkEntityPermission(entity, UPDATE);
+ }
+ catch (NotEntityException e)
+ {
+ // Not a JPA entity
+ }
+
+ return wrappedInterceptor != null ?
+ wrappedInterceptor.onFlushDirty(entity, id, currentState,
+ previousState, propertyNames, types) : false;
+ }
+
+ @Override
+ public boolean onSave(Object entity, Serializable id, Object[] state,
+ String[] propertyNames, Type[] types)
+ {
+ try
+ {
+ EntityPermissionChecker.instance().checkEntityPermission(entity, INSERT);
+ }
+ catch (NotEntityException e)
+ {
+ // Not a JPA entity
+ }
+
+ return wrappedInterceptor != null ?
+ wrappedInterceptor.onSave(entity, id, state, propertyNames, types) :
+ false;
+ }
+ */
+}
Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/JaasConfiguration.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/JaasConfiguration.java (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/JaasConfiguration.java 2010-04-13 10:40:40 UTC (rev 12453)
@@ -0,0 +1,53 @@
+package org.jboss.seam.security;
+
+import java.util.HashMap;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Produces;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
+
+import org.jboss.seam.security.jaas.SeamLoginModule;
+
+/**
+ * Producer for the JAAS Configuration used by Seam Security.
+ *
+ * @author Shane Bryzak
+ *
+ */
+public class JaasConfiguration
+{
+ static final String DEFAULT_JAAS_CONFIG_NAME = "default";
+
+ protected Configuration createConfiguration()
+ {
+ return new Configuration()
+ {
+ private AppConfigurationEntry[] aces = { createAppConfigurationEntry() };
+
+ @Override
+ public AppConfigurationEntry[] getAppConfigurationEntry(String name)
+ {
+ return DEFAULT_JAAS_CONFIG_NAME.equals(name) ? aces : null;
+ }
+
+ @Override
+ public void refresh() {}
+ };
+ }
+
+ protected AppConfigurationEntry createAppConfigurationEntry()
+ {
+ return new AppConfigurationEntry(
+ SeamLoginModule.class.getName(),
+ LoginModuleControlFlag.REQUIRED,
+ new HashMap<String,String>()
+ );
+ }
+
+ @Produces @ApplicationScoped Configuration getConfiguration()
+ {
+ return createConfiguration();
+ }
+}
Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/JpaTokenStore.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/JpaTokenStore.java (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/JpaTokenStore.java 2010-04-13 10:40:40 UTC (rev 12453)
@@ -0,0 +1,145 @@
+package org.jboss.seam.security;
+
+import java.io.Serializable;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.enterprise.inject.Instance;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.persistence.EntityManager;
+import javax.persistence.NoResultException;
+import javax.persistence.Query;
+
+import org.jboss.seam.security.annotations.TokenUsername;
+import org.jboss.seam.security.annotations.TokenValue;
+import org.jboss.seam.security.management.IdentityManagementException;
+import org.jboss.seam.security.util.AnnotatedBeanProperty;
+
+/**
+ * A TokenStore implementation, stores tokens inside a database table.
+ *
+ * @author Shane Bryzak
+ */
+ at ApplicationScoped
+public class JpaTokenStore implements TokenStore, Serializable
+{
+ private static final long serialVersionUID = -1984227349549914828L;
+
+ private Class<?> tokenEntityClass;
+
+ private AnnotatedBeanProperty<TokenUsername> tokenUsernameProperty;
+ private AnnotatedBeanProperty<TokenValue> tokenValueProperty;
+
+ @Inject BeanManager manager;
+
+ @Inject Instance<EntityManager> entityManagerInstance;
+
+ @Inject
+ public void create()
+ {
+ tokenUsernameProperty = new AnnotatedBeanProperty<TokenUsername>(tokenEntityClass, TokenUsername.class);
+ tokenValueProperty = new AnnotatedBeanProperty<TokenValue>(tokenEntityClass, TokenValue.class);
+
+ if (!tokenUsernameProperty.isSet())
+ {
+ throw new IllegalStateException("Invalid tokenClass " + tokenEntityClass.getName() +
+ " - required annotation @TokenUsername not found on any Field or Method.");
+ }
+
+ if (!tokenValueProperty.isSet())
+ {
+ throw new IllegalStateException("Invalid tokenClass " + tokenEntityClass.getName() +
+ " - required annotation @TokenValue not found on any Field or Method.");
+ }
+ }
+
+ public void createToken(String username, String value)
+ {
+ if (tokenEntityClass == null)
+ {
+ throw new IllegalStateException("Could not create token, tokenEntityClass not set");
+ }
+
+ try
+ {
+ Object token = tokenEntityClass.newInstance();
+
+ tokenUsernameProperty.setValue(token, username);
+ tokenValueProperty.setValue(token, value);
+
+ lookupEntityManager().persist(token);
+ }
+ catch (Exception ex)
+ {
+ if (ex instanceof IdentityManagementException)
+ {
+ throw (IdentityManagementException) ex;
+ }
+ else
+ {
+ throw new IdentityManagementException("Could not create account", ex);
+ }
+ }
+ }
+
+ public boolean validateToken(String username, String value)
+ {
+ return lookupToken(username, value) != null;
+ }
+
+ public void invalidateToken(String username, String value)
+ {
+ Object token = lookupToken(username, value);
+ if (token != null)
+ {
+ lookupEntityManager().remove(token);
+ }
+ }
+
+ public void invalidateAll(String username)
+ {
+ Query query = lookupEntityManager().createQuery(
+ "select t from " + tokenEntityClass.getName() + " t where " + tokenUsernameProperty.getName() +
+ " = :username")
+ .setParameter("username", username);
+
+ for (Object token : query.getResultList())
+ {
+ lookupEntityManager().remove(token);
+ }
+ }
+
+ public Object lookupToken(String username, String value)
+ {
+ try
+ {
+ Object token = lookupEntityManager().createQuery(
+ "select t from " + tokenEntityClass.getName() + " t where " + tokenUsernameProperty.getName() +
+ " = :username and " + tokenValueProperty.getName() + " = :value")
+ .setParameter("username", username)
+ .setParameter("value", value)
+ .getSingleResult();
+
+ return token;
+ }
+ catch (NoResultException ex)
+ {
+ return null;
+ }
+ }
+
+ public Class<?> getTokenEntityClass()
+ {
+ return tokenEntityClass;
+ }
+
+ public void setTokenEntityClass(Class<?> tokenEntityClass)
+ {
+ this.tokenEntityClass = tokenEntityClass;
+ }
+
+ private EntityManager lookupEntityManager()
+ {
+ return entityManagerInstance.get();
+ }
+}
Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/NotLoggedInException.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/NotLoggedInException.java (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/NotLoggedInException.java 2010-04-13 10:40:40 UTC (rev 12453)
@@ -0,0 +1,11 @@
+package org.jboss.seam.security;
+
+//import javax.ejb.ApplicationException;
+
+/**
+ * Thrown when an unauthenticated user attempts to execute a restricted action.
+ *
+ * @author Shane Bryzak
+ */
+//@ApplicationException(rollback=true)
+public class NotLoggedInException extends SecurityException {}
Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/RememberMe.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/RememberMe.java (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/RememberMe.java 2010-04-13 10:40:40 UTC (rev 12453)
@@ -0,0 +1,361 @@
+package org.jboss.seam.security;
+
+import java.io.Serializable;
+import java.rmi.server.UID;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import javax.enterprise.context.SessionScoped;
+import javax.enterprise.event.Observes;
+import javax.inject.Inject;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Named;
+
+import org.jboss.seam.security.events.CredentialsInitializedEvent;
+import org.jboss.seam.security.events.LoggedOutEvent;
+import org.jboss.seam.security.events.PostAuthenticateEvent;
+import org.jboss.seam.security.events.QuietLoginEvent;
+import org.jboss.seam.security.management.IdentityManager;
+import org.jboss.seam.security.util.Base64;
+//import org.jboss.seam.web.ManagedCookie;
+
+/**
+ * Remember-me functionality is provided by this class, in two different flavours. The first mode
+ * provides username-only persistence, and is considered to be secure as the user (or their browser)
+ * is still required to provide a password. The second mode provides an auto-login feature, however
+ * is NOT considered to be secure and is vulnerable to XSS attacks compromising the user's account.
+ *
+ * Use the auto-login mode with caution!
+ *
+ *
+ * @author Shane Bryzak
+ */
+ at Named
+ at SessionScoped
+public class RememberMe implements Serializable
+{
+ private static final long serialVersionUID = 2242379431576068199L;
+
+ public enum Mode { disabled, usernameOnly, autoLogin}
+
+ @Inject BeanManager manager;
+ @Inject Identity identity;
+ @Inject Credentials credentials;
+ @Inject IdentityManager identityManager;
+
+ // Heaps of stuff commented out here because we need to add generic cookie support
+
+ //private ManagedCookie usernameSelector;
+ //private ManagedCookie tokenSelector;
+
+ private TokenStore tokenStore;
+
+ private boolean enabled;
+
+ //private int cookieMaxAge = ManagedCookie.DEFAULT_MAX_AGE;
+
+ private boolean autoLoggedIn;
+
+ private Random random = new Random(System.currentTimeMillis());
+
+ private Mode mode = Mode.usernameOnly;
+
+ public RememberMe() {}
+
+ /*
+ public
+ @Inject
+ void create()
+ {
+ if (mode.equals(Mode.usernameOnly))
+ {
+ usernameSelector = (ManagedCookie) BeanManagerHelper.getInstanceByType(manager, ManagedCookie.class);
+ usernameSelector.setCookieName("org.jboss.seam.security.username");
+ usernameSelector.setCookieEnabled(enabled);
+ }
+ else if (mode.equals(Mode.autoLogin))
+ {
+ tokenSelector = (ManagedCookie) BeanManagerHelper.getInstanceByType(manager, ManagedCookie.class);
+ tokenSelector.setCookieName("org.jboss.seam.security.authtoken");
+ tokenSelector.setCookieEnabled(enabled);
+
+ // Default to JpaTokenStore
+ if (tokenStore == null)
+ {
+ tokenStore = BeanManagerHelper.getInstanceByType(manager,JpaTokenStore.class);
+ }
+ }
+ }
+
+ public void initCredentials(@Observes CredentialsInitializedEvent event)
+ {
+ // FIXME use the context path as the cookie path
+ // String cookiePath = getCookiePath();
+ String cookiePath = "/";
+
+ if (mode.equals(Mode.usernameOnly))
+ {
+ if (cookiePath != null)
+ {
+ usernameSelector.setCookiePath(cookiePath);
+ }
+
+ String username = usernameSelector.getCookieValue();
+ if (username!=null)
+ {
+ setEnabled(true);
+ event.getCredentials().setUsername(username);
+ }
+ }
+ else if (mode.equals(Mode.autoLogin))
+ {
+ if (cookiePath != null)
+ {
+ tokenSelector.setCookiePath(cookiePath);
+ }
+
+ String token = tokenSelector.getCookieValue();
+ if (token != null)
+ {
+ setEnabled(true);
+
+ DecodedToken decoded = new DecodedToken(token);
+
+ if (tokenStore.validateToken(decoded.getUsername(), decoded.getValue()))
+ {
+ event.getCredentials().setUsername(decoded.getUsername());
+ event.getCredentials().setPassword(decoded.getValue());
+ }
+ else
+ {
+ // Have we been compromised? Just in case, invalidate all authentication tokens
+ tokenStore.invalidateAll(decoded.getUsername());
+ }
+ }
+ }
+ }*/
+
+ public void quietLogin(@Observes QuietLoginEvent event)
+ {
+ if (mode.equals(Mode.autoLogin) && isEnabled())
+ {
+ final String username = credentials.getUsername();
+ final BoolWrapper userEnabled = new BoolWrapper();
+ final List<String> roles = new ArrayList<String>();
+
+ // Double check our credentials again
+ if (tokenStore.validateToken(username, credentials.getPassword()))
+ {
+ identity.runAs(new RunAsOperation(true) {
+ @Override
+ public void execute()
+ {
+ if (identityManager.isUserEnabled(username))
+ {
+ userEnabled.value = true;
+
+ for (String role : identityManager.getImpliedRoles(username))
+ {
+ roles.add(role);
+ }
+ }
+ }
+ });
+
+ if (userEnabled.value)
+ {
+ identity.unAuthenticate();
+ identity.preAuthenticate();
+
+ // populate the roles
+ for (String role : roles)
+ {
+ identity.addRole(role);
+ }
+
+ // Set the principal
+ identity.getSubject().getPrincipals().add(new SimplePrincipal(username));
+ identity.postAuthenticate();
+
+ autoLoggedIn = true;
+ }
+ }
+ }
+ }
+ /*
+ public void postAuthenticate(@Observes PostAuthenticateEvent event)
+ {
+ if (mode.equals(Mode.usernameOnly))
+ {
+ if ( !enabled )
+ {
+ usernameSelector.clearCookieValue();
+ }
+ else
+ {
+ usernameSelector.setCookieMaxAge(cookieMaxAge);
+ usernameSelector.setCookieValueIfEnabled( credentials.getUsername() );
+ }
+ }
+ else if (mode.equals(Mode.autoLogin))
+ {
+ DecodedToken decoded = new DecodedToken(tokenSelector.getCookieValue());
+
+ // Invalidate the current token (if it exists) whether enabled or not
+ if (decoded.getUsername() != null)
+ {
+ tokenStore.invalidateToken(decoded.getUsername(), decoded.getValue());
+ }
+
+ if ( !enabled )
+ {
+ tokenSelector.clearCookieValue();
+ }
+ else
+ {
+ String value = generateTokenValue();
+ tokenStore.createToken(identity.getPrincipal().getName(), value);
+ tokenSelector.setCookieEnabled(enabled);
+ tokenSelector.setCookieMaxAge(cookieMaxAge);
+ tokenSelector.setCookieValueIfEnabled(encodeToken(identity.getPrincipal().getName(), value));
+ }
+ }
+ }
+ */
+
+ /*
+ public void loggedOut(@Observes LoggedOutEvent event)
+ {
+ if (mode.equals(Mode.autoLogin))
+ {
+ tokenSelector.clearCookieValue();
+ }
+ }*/
+
+ public Mode getMode()
+ {
+ return mode;
+ }
+
+ public void setMode(Mode mode)
+ {
+ this.mode = mode;
+ }
+
+ public boolean isEnabled()
+ {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled)
+ {
+ this.enabled = enabled;
+ }
+
+ /*
+ public void setEnabled(boolean enabled)
+ {
+ if (this.enabled != enabled)
+ {
+ this.enabled = enabled;
+ // selector is null during component initialization (setup handled in @Create method)
+ if (usernameSelector != null && mode.equals(Mode.usernameOnly))
+ {
+ usernameSelector.setCookieEnabled(enabled);
+ }
+ // selector is null during component initialization (setup handled in @Create method)
+ else if (tokenSelector != null && mode.equals(Mode.autoLogin))
+ {
+ tokenSelector.setCookieEnabled(enabled);
+ }
+ }
+ }*/
+
+ /*
+ public int getCookieMaxAge() {
+ return cookieMaxAge;
+ }
+
+ public void setCookieMaxAge(int cookieMaxAge) {
+ this.cookieMaxAge = cookieMaxAge;
+ }*/
+
+ public TokenStore getTokenStore()
+ {
+ return tokenStore;
+ }
+
+ public void setTokenStore(TokenStore tokenStore)
+ {
+ this.tokenStore = tokenStore;
+ }
+
+ /**
+ * A flag that an application can use to protect sensitive operations if the user has been
+ * auto-authenticated.
+ */
+ public boolean isAutoLoggedIn()
+ {
+ return autoLoggedIn;
+ }
+
+ protected String generateTokenValue()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.append(new UID().toString());
+ sb.append(":");
+ sb.append(random.nextLong());
+ return sb.toString();
+ }
+
+ protected String encodeToken(String username, String value)
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.append(username);
+ sb.append(":");
+ sb.append(value);
+ return Base64.encodeBytes(sb.toString().getBytes());
+ }
+
+ /**
+ * I hate these hacks...
+ */
+ private class BoolWrapper
+ {
+ boolean value;
+ }
+
+ private class DecodedToken
+ {
+ private String username;
+ private String value;
+
+ public DecodedToken(String cookieValue)
+ {
+ if (cookieValue != null)
+ {
+ try
+ {
+ String decoded = new String(Base64.decode(cookieValue));
+ username = decoded.substring(0, decoded.indexOf(':'));
+ value = decoded.substring(decoded.indexOf(':') + 1);
+ }
+ catch (Exception ex)
+ {
+ // intentionally swallow
+ }
+ }
+ }
+
+ public String getUsername()
+ {
+ return username;
+ }
+
+ public String getValue()
+ {
+ return value;
+ }
+ }
+}
Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/RequestSecurityState.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/RequestSecurityState.java (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/RequestSecurityState.java 2010-04-13 10:40:40 UTC (rev 12453)
@@ -0,0 +1,35 @@
+package org.jboss.seam.security;
+
+import javax.enterprise.context.RequestScoped;
+
+/**
+ * Contains the authentication state of the current request
+ *
+ * @author Shane Bryzak
+ */
+ at RequestScoped
+public class RequestSecurityState
+{
+ private boolean silentLogin;
+ private boolean loginTried;
+
+ public boolean isSilentLogin()
+ {
+ return silentLogin;
+ }
+
+ public void setSilentLogin(boolean silentLogin)
+ {
+ this.silentLogin = silentLogin;
+ }
+
+ public boolean isLoginTried()
+ {
+ return loginTried;
+ }
+
+ public void setLoginTried(boolean loginTried)
+ {
+ this.loginTried = loginTried;
+ }
+}
Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/Role.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/Role.java (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/Role.java 2010-04-13 10:40:40 UTC (rev 12453)
@@ -0,0 +1,30 @@
+package org.jboss.seam.security;
+
+/**
+ * Represents a user role. A conditional role is a special type of role that is assigned to a user
+ * based on the contextual state of a permission check.
+ *
+ * @author Shane Bryzak
+ */
+public class Role extends SimplePrincipal
+{
+ private static final long serialVersionUID = 1187276024036531700L;
+
+ private boolean conditional;
+
+ public Role(String name)
+ {
+ super(name);
+ }
+
+ public Role(String name, boolean conditional)
+ {
+ this(name);
+ this.conditional = conditional;
+ }
+
+ public boolean isConditional()
+ {
+ return conditional;
+ }
+}
Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/RunAsOperation.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/RunAsOperation.java (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/RunAsOperation.java 2010-04-13 10:40:40 UTC (rev 12453)
@@ -0,0 +1,72 @@
+package org.jboss.seam.security;
+
+import java.security.Principal;
+import java.security.acl.Group;
+
+import javax.security.auth.Subject;
+
+/**
+ * Defines a security operation that can be executed within a particular
+ * security context.
+ *
+ * @author Shane Bryzak
+ */
+public abstract class RunAsOperation
+{
+ private Principal principal;
+ private Subject subject;
+
+ private boolean systemOp = false;
+
+ public RunAsOperation()
+ {
+ principal = new SimplePrincipal(null);
+ subject = new Subject();
+ }
+
+ /**
+ * A system operation allows any security checks to pass
+ *
+ * @param systemOp
+ */
+ public RunAsOperation(boolean systemOp)
+ {
+ this();
+ this.systemOp = systemOp;
+ }
+
+ public abstract void execute();
+
+ public Principal getPrincipal()
+ {
+ return principal;
+ }
+
+ public Subject getSubject()
+ {
+ return subject;
+ }
+
+ public RunAsOperation addRole(String role)
+ {
+ for ( Group sg : getSubject().getPrincipals(Group.class) )
+ {
+ if ( Identity.ROLES_GROUP.equals( sg.getName() ) )
+ {
+ sg.addMember(new SimplePrincipal(role));
+ break;
+ }
+ }
+
+ SimpleGroup roleGroup = new SimpleGroup(Identity.ROLES_GROUP);
+ roleGroup.addMember(new SimplePrincipal(role));
+ getSubject().getPrincipals().add(roleGroup);
+
+ return this;
+ }
+
+ public boolean isSystemOperation()
+ {
+ return systemOp;
+ }
+}
Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/Secure.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/Secure.java (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/Secure.java 2010-04-13 10:40:40 UTC (rev 12453)
@@ -0,0 +1,24 @@
+package org.jboss.seam.security;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.interceptor.InterceptorBinding;
+
+/**
+ *
+ * @author Shane Bryzak
+ */
+ at Inherited
+ at InterceptorBinding
+ at Target({TYPE, METHOD})
+ at Retention(RUNTIME)
+public @interface Secure
+{
+
+}
Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/SecurityEventMessages.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/SecurityEventMessages.java (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/SecurityEventMessages.java 2010-04-13 10:40:40 UTC (rev 12453)
@@ -0,0 +1,130 @@
+package org.jboss.seam.security;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.enterprise.event.Observes;
+
+//import org.jboss.seam.international.StatusMessages;
+//import org.jboss.seam.international.StatusMessage.Severity;
+import org.jboss.seam.security.events.AlreadyLoggedInEvent;
+import org.jboss.seam.security.events.LoggedInEvent;
+import org.jboss.seam.security.events.LoginFailedEvent;
+import org.jboss.seam.security.events.NotLoggedInEvent;
+import org.jboss.seam.security.events.PostAuthenticateEvent;
+
+/**
+ * Produces FacesMessages in response of certain security events, and helps to
+ * decouple the Identity component from JSF.
+ *
+ * @author Shane Bryzak
+ */
+public
+ at ApplicationScoped
+class SecurityEventMessages
+{
+ private static final String LOGIN_FAILED_MESSAGE_KEY = "org.jboss.seam.loginFailed";
+ private static final String LOGIN_SUCCESSFUL_MESSAGE_KEY = "org.jboss.seam.loginSuccessful";
+ private static final String ALREADY_LOGGED_IN_MESSAGE_KEY = "org.jboss.seam.alreadyLoggedIn";
+ private static final String NOT_LOGGED_IN_MESSAGE_KEY = "org.jboss.seam.notLoggedIn";
+
+ private static final String DEFAULT_LOGIN_FAILED_MESSAGE = "Login failed.";
+ private static final String DEFAULT_LOGIN_SUCCESSFUL_MESSAGE = "Welcome, {0}.";
+ private static final String DEFAULT_ALREADY_LOGGED_IN_MESSAGE = "You're already logged in. Please log out first if you wish to log in again.";
+ private static final String DEFAULT_NOT_LOGGED_IN_MESSAGE = "Please log in first.";
+
+ //@Inject StatusMessages statusMessages;
+ @Inject Credentials credentials;
+
+ public void postAuthenticate(@Observes PostAuthenticateEvent event)
+ {
+ // org.jboss.security.saml.SSOManager.processManualLoginNotification(
+ // ServletContexts.instance().getRequest(),
+ // identity.getPrincipal().getName());
+ }
+
+ public void addLoginFailedMessage(@Observes LoginFailedEvent event)
+ {
+ //statusMessages.addFromResourceBundleOrDefault(getLoginFailedMessageSeverity(), getLoginFailedMessageKey(), getDefaultLoginFailedMessage(), event.getLoginException());
+ }
+
+ public void addLoginSuccessMessage(@Observes LoggedInEvent event)
+ {
+ // statusMessages.addFromResourceBundleOrDefault(getLoginSuccessfulMessageSeverity(), getLoginSuccessfulMessageKey(), getDefaultLoginSuccessfulMessage(), credentials.getUsername());
+ }
+
+ public void addAlreadyLoggedInMessage(@Observes AlreadyLoggedInEvent event)
+ {
+ //statusMessages.addFromResourceBundleOrDefault(getAlreadyLoggedInMessageSeverity(), getAlreadyLoggedInMessageKey(), getDefaultAlreadyLoggedInMessage());
+ }
+
+ public void addNotLoggedInMessage(@Observes NotLoggedInEvent event)
+ {
+ //statusMessages.addFromResourceBundleOrDefault(getNotLoggedInMessageSeverity(), getNotLoggedInMessageKey(), getDefaultNotLoggedInMessage());
+ }
+
+ // TODO the following methods should probably be moved to the seam-jsf module,
+ // or otherwise message severities should be abstracted in seam-international
+
+ /*public Severity getLoginFailedMessageSeverity()
+ {
+ return Severity.INFO;
+ }
+
+ public Severity getLoginSuccessfulMessageSeverity()
+ {
+ return Severity.INFO;
+ }
+
+ public Severity getAlreadyLoggedInMessageSeverity()
+ {
+ return Severity.INFO;
+ }
+
+ public Severity getNotLoggedInMessageSeverity()
+ {
+ return Severity.WARN;
+ }
+*/
+
+ public String getLoginFailedMessageKey()
+ {
+ return LOGIN_FAILED_MESSAGE_KEY;
+ }
+
+ public String getDefaultLoginFailedMessage()
+ {
+ return DEFAULT_LOGIN_FAILED_MESSAGE;
+ }
+
+
+ public String getLoginSuccessfulMessageKey()
+ {
+ return LOGIN_SUCCESSFUL_MESSAGE_KEY;
+ }
+
+ public String getDefaultLoginSuccessfulMessage()
+ {
+ return DEFAULT_LOGIN_SUCCESSFUL_MESSAGE;
+ }
+
+ public String getAlreadyLoggedInMessageKey()
+ {
+ return ALREADY_LOGGED_IN_MESSAGE_KEY;
+ }
+
+ public String getDefaultAlreadyLoggedInMessage()
+ {
+ return DEFAULT_ALREADY_LOGGED_IN_MESSAGE;
+ }
+
+ public String getNotLoggedInMessageKey()
+ {
+ return NOT_LOGGED_IN_MESSAGE_KEY;
+ }
+
+ public String getDefaultNotLoggedInMessage()
+ {
+ return DEFAULT_NOT_LOGGED_IN_MESSAGE;
+ }
+
+}
Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/SecurityException.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/SecurityException.java (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/SecurityException.java 2010-04-13 10:40:40 UTC (rev 12453)
@@ -0,0 +1,31 @@
+package org.jboss.seam.security;
+
+/**
+ * Any exception that is raised by the security module extends from this runtime
+ * exception class, making it easy for other modules and extensions to catch all
+ * security-related exceptions in a single catch block, if need be.
+ *
+ * @author Dan Allen
+ */
+public abstract class SecurityException extends RuntimeException
+{
+ public SecurityException()
+ {
+ super();
+ }
+
+ public SecurityException(String message, Throwable cause)
+ {
+ super(message, cause);
+ }
+
+ public SecurityException(String message)
+ {
+ super(message);
+ }
+
+ public SecurityException(Throwable cause)
+ {
+ super(cause);
+ }
+}
Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/SecurityInterceptor.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/SecurityInterceptor.java (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/SecurityInterceptor.java 2010-04-13 10:40:40 UTC (rev 12453)
@@ -0,0 +1,302 @@
+package org.jboss.seam.security;
+
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.interceptor.AroundInvoke;
+import javax.interceptor.Interceptor;
+import javax.interceptor.InvocationContext;
+
+import org.jboss.seam.security.annotations.PermissionCheck;
+import org.jboss.seam.security.annotations.Restrict;
+import org.jboss.seam.security.annotations.RoleCheck;
+import org.jboss.seam.security.util.Strings;
+
+/**
+ * Provides authorization services for component invocations.
+ *
+ * @author Shane Bryzak
+ */
+ at Secure @Interceptor
+public class SecurityInterceptor implements Serializable
+{
+ private static final long serialVersionUID = -6567750187000766925L;
+
+ /**
+ * You may encounter a JVM bug where the field initializer is not evaluated for a transient field after deserialization.
+ * @see "http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6252102"
+ */
+ private transient volatile Map<Method,Restriction> restrictions = new HashMap<Method,Restriction>();
+
+ @Inject BeanManager manager;
+ @Inject Identity identity;
+
+ private class Restriction
+ {
+ private String expression;
+
+ private String permissionTarget;
+ private String permissionAction;
+
+ private Map<String, Object> methodRestrictions;
+ private Map<Integer,Set<String>> paramRestrictions;
+ private Set<String> roleRestrictions;
+
+ public void setExpression(String expression)
+ {
+ this.expression = expression;
+ }
+
+ public void setPermissionTarget(String target)
+ {
+ this.permissionTarget = target;
+ }
+
+ public void setPermissionAction(String action)
+ {
+ this.permissionAction = action;
+ }
+
+ public void addMethodRestriction(Object target, String action)
+ {
+ if (methodRestrictions == null)
+ {
+ methodRestrictions = new HashMap<String, Object>();
+ }
+
+ methodRestrictions.put(action, target);
+ }
+
+ public void addRoleRestriction(String role)
+ {
+ if (roleRestrictions == null)
+ {
+ roleRestrictions = new HashSet<String>();
+ }
+
+ roleRestrictions.add(role);
+ }
+
+ public void addParameterRestriction(int index, String action)
+ {
+ Set<String> actions = null;
+
+ if (paramRestrictions == null)
+ {
+ paramRestrictions = new HashMap<Integer,Set<String>>();
+ }
+
+ if (!paramRestrictions.containsKey(index))
+ {
+ actions = new HashSet<String>();
+ paramRestrictions.put(index, actions);
+ }
+ else
+ {
+ actions = paramRestrictions.get(index);
+ }
+
+ actions.add(action);
+ }
+
+ public void check(Identity identity, Object[] parameters)
+ {
+ if (Identity.isSecurityEnabled())
+ {
+ // TODO rewrite EL based restrictions
+ /*if (expression != null)
+ {
+ identity.checkRestriction(expression);
+ }*/
+
+ if (methodRestrictions != null)
+ {
+ for (String action : methodRestrictions.keySet())
+ {
+ identity.checkPermission(methodRestrictions.get(action), action);
+ }
+ }
+
+ if (paramRestrictions != null)
+ {
+ for (Integer idx : paramRestrictions.keySet())
+ {
+ Set<String> actions = paramRestrictions.get(idx);
+ for (String action : actions)
+ {
+ identity.checkPermission(parameters[idx], action);
+ }
+ }
+ }
+
+ if (roleRestrictions != null)
+ {
+ for (String role : roleRestrictions)
+ {
+ identity.checkRole(role);
+ }
+ }
+
+ if (permissionTarget != null && permissionAction != null)
+ {
+ identity.checkPermission(permissionTarget, permissionAction);
+ }
+ }
+ }
+ }
+
+ @AroundInvoke
+ public Object aroundInvoke(InvocationContext invocation) throws Exception
+ {
+ Method interfaceMethod = invocation.getMethod();
+
+ if (!"hashCode".equals(interfaceMethod.getName()))
+ {
+ Restriction restriction = getRestriction(interfaceMethod);
+ if ( restriction != null )
+ {
+
+ restriction.check(identity, invocation.getParameters());
+ }
+ }
+
+ return invocation.proceed();
+ }
+
+ private Restriction getRestriction(Method interfaceMethod) throws Exception
+ {
+ // see field declaration as to why this is done
+ if (restrictions == null)
+ {
+ synchronized(this)
+ {
+ restrictions = new HashMap<Method, Restriction>();
+ }
+ }
+
+ if (!restrictions.containsKey(interfaceMethod))
+ {
+ synchronized(restrictions)
+ {
+ // FIXME this logic should be abstracted rather than sitting in the middle of this interceptor
+ if (!restrictions.containsKey(interfaceMethod))
+ {
+ Restriction restriction = null;
+
+ /*Method method = getComponent().getBeanClass().getMethod(
+ interfaceMethod.getName(), interfaceMethod.getParameterTypes() );*/
+
+ Restrict restrict = null;
+
+ if ( interfaceMethod.isAnnotationPresent(Restrict.class) )
+ {
+ restrict = interfaceMethod.getAnnotation(Restrict.class);
+ }
+ else if ( interfaceMethod.getDeclaringClass().isAnnotationPresent(Restrict.class) )
+ {
+ restrict = interfaceMethod.getDeclaringClass().getAnnotation(Restrict.class);
+ }
+
+ if (restrict != null)
+ {
+ if (restriction == null) restriction = new Restriction();
+
+ if ( Strings.isEmpty(restrict.value()) )
+ {
+ Bean<?> bean = manager.getBeans(interfaceMethod.getDeclaringClass()).iterator().next();
+ restriction.setPermissionTarget(bean.getName());
+ restriction.setPermissionAction(interfaceMethod.getName());
+ }
+ else
+ {
+ restriction.setExpression(restrict.value());
+ }
+ }
+
+ for (Annotation annotation : interfaceMethod.getDeclaringClass().getAnnotations())
+ {
+ if (annotation.annotationType().isAnnotationPresent(RoleCheck.class))
+ {
+ if (restriction == null) restriction = new Restriction();
+ restriction.addRoleRestriction(annotation.annotationType().getSimpleName().toLowerCase());
+ }
+ }
+
+ for (Annotation annotation : interfaceMethod.getAnnotations())
+ {
+ if (annotation.annotationType().isAnnotationPresent(PermissionCheck.class))
+ {
+ PermissionCheck permissionCheck = annotation.annotationType().getAnnotation(
+ PermissionCheck.class);
+
+ Method valueMethod = null;
+ for (Method m : annotation.annotationType().getDeclaredMethods())
+ {
+ valueMethod = m;
+ break;
+ }
+
+ if (valueMethod != null)
+ {
+ if (restriction == null) restriction = new Restriction();
+ Object target = valueMethod.invoke(annotation);
+ if (!target.equals(void.class))
+ {
+ if (restriction == null) restriction = new Restriction();
+ restriction.addMethodRestriction(target,
+ getPermissionAction(permissionCheck, annotation));
+ }
+ }
+ }
+ if (annotation.annotationType().isAnnotationPresent(RoleCheck.class))
+ {
+ if (restriction == null) restriction = new Restriction();
+ restriction.addRoleRestriction(annotation.annotationType().getSimpleName().toLowerCase());
+ }
+ }
+
+ for (int i = 0; i < interfaceMethod.getParameterAnnotations().length; i++)
+ {
+ Annotation[] annotations = interfaceMethod.getParameterAnnotations()[i];
+ for (Annotation annotation : annotations)
+ {
+ if (annotation.annotationType().isAnnotationPresent(PermissionCheck.class))
+ {
+ PermissionCheck permissionCheck = annotation.annotationType().getAnnotation(
+ PermissionCheck.class);
+ if (restriction == null) restriction = new Restriction();
+ restriction.addParameterRestriction(i,
+ getPermissionAction(permissionCheck, annotation));
+ }
+ }
+ }
+
+ restrictions.put(interfaceMethod, restriction);
+ return restriction;
+ }
+ }
+ }
+ return restrictions.get(interfaceMethod);
+ }
+
+
+ private String getPermissionAction(PermissionCheck check, Annotation annotation)
+ {
+ if (!"".equals(check.value()))
+ {
+ return check.value();
+ }
+ else
+ {
+ return annotation.annotationType().getSimpleName().toLowerCase();
+ }
+ }
+}
Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/SimpleGroup.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/SimpleGroup.java (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/SimpleGroup.java 2010-04-13 10:40:40 UTC (rev 12453)
@@ -0,0 +1,93 @@
+package org.jboss.seam.security;
+
+import java.io.Serializable;
+import java.security.Principal;
+import java.security.acl.Group;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Implementation of the Group interface, used for holding roles etc.
+ *
+ * @author Shane Bryzak
+ */
+public class SimpleGroup implements Group, Serializable
+{
+ private static final long serialVersionUID = 5766373925836425908L;
+
+ /**
+ * The name of the group
+ */
+ private String name;
+
+ /**
+ * The members of this group
+ */
+ private Set<Principal> members = new HashSet<Principal>();
+
+ public SimpleGroup(String name)
+ {
+ this.name = name;
+ }
+
+ public boolean addMember(Principal user)
+ {
+ return members.add(user);
+ }
+
+ public boolean isMember(Principal member)
+ {
+ if ( members.contains(member) )
+ {
+ return true;
+ }
+ else
+ {
+ for (Principal m : members)
+ {
+ if (m instanceof Group && ((Group) m).isMember(member))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public Enumeration<? extends Principal> members()
+ {
+ return Collections.enumeration(members);
+ }
+
+ public boolean removeMember(Principal user)
+ {
+ return members.remove(user);
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj instanceof SimpleGroup)
+ {
+ SimpleGroup other = (SimpleGroup) obj;
+ return other.name.equals(name);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return name.hashCode();
+ }
+}
Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/SimplePrincipal.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/SimplePrincipal.java (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/SimplePrincipal.java 2010-04-13 10:40:40 UTC (rev 12453)
@@ -0,0 +1,54 @@
+package org.jboss.seam.security;
+
+import java.io.Serializable;
+import java.security.Principal;
+
+/**
+ * Simple implementation of the Principal interface, supporting a named user.
+ *
+ * @author Shane Bryzak
+ */
+public class SimplePrincipal implements Principal, Serializable
+{
+ private static final long serialVersionUID = 5609375932836425908L;
+
+ private String name;
+
+ public SimplePrincipal(String name)
+ {
+ this.name = name;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj instanceof Principal)
+ {
+ Principal other = (Principal) obj;
+ return name == null ?
+ other.getName() == null :
+ name.equals( other.getName() );
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return name != null ? name.hashCode() : super.hashCode();
+ }
+
+ @Override
+ public String toString()
+ {
+ return name;
+ }
+}
Added: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/TokenStore.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/TokenStore.java (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/TokenStore.java 2010-04-13 10:40:40 UTC (rev 12453)
@@ -0,0 +1,15 @@
+package org.jboss.seam.security;
+
+/**
+ * A store containing user authentication tokens. Used in conjunction with the RememberMe
+ * component to auto-login users that present a valid cookie-based token.
+ *
+ * @author Shane Bryzak
+ */
+public interface TokenStore
+{
+ void createToken(String username, String value);
+ boolean validateToken(String username, String value);
+ void invalidateToken(String username, String value);
+ void invalidateAll(String username);
+}
More information about the seam-commits
mailing list