FC-181 - Multitenancy for Realm
diff --git a/REALM-CONTEXT-SETUP.md b/REALM-CONTEXT-SETUP.md
index a131b90..a37fab9 100644
--- a/REALM-CONTEXT-SETUP.md
+++ b/REALM-CONTEXT-SETUP.md
@@ -92,6 +92,7 @@
defaultRoles=""
containerType="TomcatContext"
realmClasspath=""
+ contextId="HOME"
/>
</Context>
```
diff --git a/REALM-HOST-SETUP.md b/REALM-HOST-SETUP.md
index 96e9cf6..125de1c 100644
--- a/REALM-HOST-SETUP.md
+++ b/REALM-HOST-SETUP.md
@@ -157,6 +157,7 @@
containerType="Tomcat7"
realmClasspath="$FORTRESS_REALM_HOME/conf:$FORTRESS_REALM_HOME/impl/target/fortress-realm-impl-uber-[version].jar"
defaultRoles=""
+ contextId="HOME"
/>
```
diff --git a/impl/pom.xml b/impl/pom.xml
index c9c28b6..1ff8598 100644
--- a/impl/pom.xml
+++ b/impl/pom.xml
@@ -52,6 +52,13 @@
<artifactId>fortress-core</artifactId>
<version>${fortress-core.version}</version>
</dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>${slf4j.log4j12.version}</version>
+ </dependency>
+
</dependencies>
<build>
diff --git a/impl/src/main/java/org/apache/directory/fortress/realm/J2eePolicyMgr.java b/impl/src/main/java/org/apache/directory/fortress/realm/J2eePolicyMgr.java
index a3f1656..379edec 100644
--- a/impl/src/main/java/org/apache/directory/fortress/realm/J2eePolicyMgr.java
+++ b/impl/src/main/java/org/apache/directory/fortress/realm/J2eePolicyMgr.java
@@ -47,7 +47,6 @@
*/
boolean authenticate( String userId, char[] password ) throws SecurityException;
-
/**
* Perform user authentication {@link User#password} and role activations.<br />
* This method must be called once per user prior to calling other methods within this class.
@@ -105,7 +104,6 @@
*/
TcPrincipal createSession( String userId, char[] password ) throws SecurityException;
-
/**
* Perform user authentication {@link User#password} and role activations.<br />
* This method must be called once per user prior to calling other methods within this class.
@@ -164,7 +162,6 @@
*/
TcPrincipal createSession( String userId, char[] password, List<String> roles ) throws SecurityException;
-
/**
* Perform user authentication {@link User#password} and role activations.<br />
* This method must be called once per user prior to calling other methods within this class.
@@ -222,7 +219,6 @@
*/
Session createSession( User user, boolean isTrusted ) throws SecurityException;
-
/**
* Determine if given Role is contained within User's Tomcat Principal object. This method does not need to hit
* the ldap server as the User's activated Roles are loaded into {@link TcPrincipal#setContext(java.util.HashMap)}
@@ -235,7 +231,6 @@
*/
boolean hasRole( Principal principal, String roleName ) throws SecurityException;
-
/**
* Method reads Role entity from the role container in directory.
*
@@ -246,7 +241,6 @@
*/
Role readRole( String roleName ) throws SecurityException;
-
/**
* Search for Roles assigned to given User.
*
@@ -258,7 +252,6 @@
*/
List<String> searchRoles( String userId, int limit ) throws SecurityException;
-
/**
* Method returns matching User entity that is contained within the people container in the directory.
*
@@ -269,7 +262,6 @@
*/
User readUser( String userId ) throws SecurityException;
-
/**
* Return a list of type String of all users in the people container that match the userId field passed in User entity.
* This method is used by the Websphere sentry component. The max number of returned users may be set by the integer limit arg.
@@ -281,7 +273,6 @@
*/
List<String> searchUsers( String userId, int limit ) throws SecurityException;
-
/**
* This function returns the set of users assigned to a given role. The function is valid if and
* only if the role is a member of the ROLES data set.
@@ -296,7 +287,6 @@
*/
List<String> assignedUsers( String roleName, int limit ) throws SecurityException;
-
/**
* This function returns the set of roles authorized for a given user. The function is valid if
* and only if the user is a member of the USERS data set.
@@ -307,7 +297,6 @@
*/
List<String> authorizedRoles( String userId ) throws SecurityException;
-
/**
* This utility method can deserialize java.security.Principal to Fortress RBAC session object.
*
@@ -315,5 +304,13 @@
* @return deserialization target object
*/
Session deserialize( String str ) throws SecurityException;
-}
+ /**
+ * Use this method to set the tenant id onto function call into Fortress which allows segregation of data by customer.
+ * The contextId is used for multi-tenancy to isolate data sets within a particular sub-tree within DIT.
+ * Setting contextId into this object will render this class' implementer thread unsafe.
+ *
+ * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+ */
+ public void setContextId(String contextId);
+}
\ No newline at end of file
diff --git a/impl/src/main/java/org/apache/directory/fortress/realm/J2eePolicyMgrFactory.java b/impl/src/main/java/org/apache/directory/fortress/realm/J2eePolicyMgrFactory.java
index d75ae10..7799371 100644
--- a/impl/src/main/java/org/apache/directory/fortress/realm/J2eePolicyMgrFactory.java
+++ b/impl/src/main/java/org/apache/directory/fortress/realm/J2eePolicyMgrFactory.java
@@ -19,9 +19,15 @@
*/
package org.apache.directory.fortress.realm;
-import org.apache.directory.fortress.core.util.Config;
+import org.apache.commons.lang.StringUtils;
+import org.apache.directory.fortress.core.*;
+import org.apache.directory.fortress.core.GlobalIds;
import org.apache.directory.fortress.core.SecurityException;
-import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.impl.AdminMgrImpl;
+import org.apache.directory.fortress.core.rest.AdminMgrRestImpl;
+import org.apache.directory.fortress.core.util.ClassUtil;
+import org.apache.directory.fortress.core.util.Config;
+import org.apache.directory.fortress.core.util.VUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -51,43 +57,42 @@
private static String j2eeClassName = Config.getInstance().getProperty( J2EE_POLICYMGR_IMPLEMENTATION );
/**
- * Create and return a reference to {@link J2eePolicyMgr} object.
+ * Create and return a reference to {@link J2eePolicyMgr} object with HOME context.
*
* @return instance of {@link J2eePolicyMgr}.
* @throws org.apache.directory.fortress.core.SecurityException in the event of failure during instantiation.
*/
public static J2eePolicyMgr createInstance() throws SecurityException
{
- J2eePolicyMgr realmMgr;
-
- try
- {
- if ( ( j2eeClassName == null ) || ( j2eeClassName.length() == 0 ) )
- {
- j2eeClassName = J2EE_POLICYMGR_DEFAULT_CLASS;
- LOG.debug( "{}.createInstance [{}], not found.", CLS_NM, J2EE_POLICYMGR_IMPLEMENTATION );
- LOG.debug( "{}.createInstance use default [{}], not found.", CLS_NM, J2EE_POLICYMGR_DEFAULT_CLASS );
- }
-
- realmMgr = (J2eePolicyMgr) Class.forName( j2eeClassName ).newInstance();
- }
- catch ( ClassNotFoundException e )
- {
- String error = CLS_NM + ".createInstance caught java.lang.ClassNotFoundException=" + e;
- throw new SecurityException( GlobalErrIds.FT_MGR_CLASS_NOT_FOUND, error, e );
- }
- catch ( InstantiationException e )
- {
- String error = CLS_NM + ".createInstance caught java.lang.InstantiationException=" + e;
- throw new SecurityException( GlobalErrIds.FT_MGR_INST_EXCEPTION, error, e );
- }
- catch ( IllegalAccessException e )
- {
- String error = CLS_NM + ".createInstance caught java.lang.IllegalAccessException=" + e;
- LOG.error( error );
- throw new SecurityException( GlobalErrIds.FT_MGR_ILLEGAL_ACCESS, error, e );
- }
-
- return realmMgr;
+ return createInstance( GlobalIds.HOME );
}
+
+
+ /**
+ * Create and return a reference to {@link J2eePolicyMgr} object with HOME context.
+ *
+ * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=example, dc=com.
+ * @return instance of {@link J2eePolicyMgr}.
+ * @throws SecurityException in the event of failure during instantiation.
+ */
+ public static J2eePolicyMgr createInstance(String contextId)
+ throws SecurityException
+ {
+ VUtil.assertNotNull( contextId, GlobalErrIds.CONTEXT_NULL, CLS_NM + ".createInstance" );
+ String j2eeClassName = Config.getInstance().getProperty( J2EE_POLICYMGR_IMPLEMENTATION );
+ J2eePolicyMgr policyMgr;
+
+ if ( StringUtils.isEmpty( j2eeClassName ) )
+ {
+ policyMgr = new J2eePolicyMgrImpl( );
+ }
+ else
+ {
+ policyMgr = ( J2eePolicyMgr ) ClassUtil.createInstance( J2EE_POLICYMGR_DEFAULT_CLASS );
+ }
+
+ policyMgr.setContextId( contextId );
+ return policyMgr;
+ }
+
}
\ No newline at end of file
diff --git a/impl/src/main/java/org/apache/directory/fortress/realm/J2eePolicyMgrImpl.java b/impl/src/main/java/org/apache/directory/fortress/realm/J2eePolicyMgrImpl.java
index b5ae44a..3c7429d 100644
--- a/impl/src/main/java/org/apache/directory/fortress/realm/J2eePolicyMgrImpl.java
+++ b/impl/src/main/java/org/apache/directory/fortress/realm/J2eePolicyMgrImpl.java
@@ -28,9 +28,11 @@
import java.util.HashMap;
import java.util.List;
import java.security.Principal;
+import java.util.NoSuchElementException;
import java.util.Set;
import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang.StringUtils;
import org.apache.directory.fortress.core.GlobalIds;
import org.apache.directory.fortress.core.ReviewMgr;
import org.apache.directory.fortress.core.ReviewMgrFactory;
@@ -46,9 +48,9 @@
import org.slf4j.LoggerFactory;
/**
- * This class is for components that use Websphere and Tomcat Container SPI's to provide
- * Java EE Security capabilities. These APIs may be called by external programs as needed though the recommended
- * practice is to use Fortress Core APIs like {@link org.apache.directory.fortress.core.AccessMgr} and {@link org.apache.directory.fortress.core.ReviewMgr}.
+ * This class contains common functions for container managed security. These APIs may be called by external programs as needed though the expected
+ * practice for external app usage is to call Apache Fortress Core APIs, e.g. {@link org.apache.directory.fortress.core.AccessMgr} and {@link org.apache.directory.fortress.core.ReviewMgr}.
+ * This class is NOT thread safe if contextId is set.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
@@ -56,17 +58,18 @@
{
private static final String CLS_NM = J2eePolicyMgrImpl.class.getName();
private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
- private static AccessMgr accessMgr;
- private static ReviewMgr reviewMgr;
+ private AccessMgr accessMgr;
+ private ReviewMgr reviewMgr;
private static final String SESSION = "session";
+ private String contextId;
- static
+ J2eePolicyMgrImpl ()
{
try
{
- accessMgr = AccessMgrFactory.createInstance( GlobalIds.HOME );
- reviewMgr = ReviewMgrFactory.createInstance( GlobalIds.HOME );
- LOG.info( "{} - Initialized successfully", CLS_NM );
+ accessMgr = AccessMgrFactory.createInstance( );
+ reviewMgr = ReviewMgrFactory.createInstance( );
+ LOG.info( "{} - constructed", CLS_NM );
}
catch ( SecurityException se )
{
@@ -74,15 +77,8 @@
}
}
-
/**
- * Perform user authentication and evaluate password policies.
- *
- * @param userId Contains the userid of the user signing on.
- * @param password Contains the user's password.
- * @return boolean true if succeeds, false otherwise.
- * @throws org.apache.directory.fortress.core.SecurityException
- * in the event of data validation failure, security policy violation or DAO error.
+ * {@inheritDoc}
*/
@Override
public boolean authenticate( String userId, char[] password ) throws SecurityException
@@ -103,74 +99,8 @@
return result;
}
-
/**
- * Perform user authentication {@link org.apache.directory.fortress.core.model.User#password} and role activations.<br />
- * This method must be called once per user prior to calling other methods within this class.
- * The successful result is {@link org.apache.directory.fortress.core.model.Session} that contains target user's RBAC {@link
- * User#roles} and Admin role {@link User#adminRoles}.<br />
- * In addition to checking user password validity it will apply configured password policy checks {@link org.openldap
- * .fortress.rbac.User#pwPolicy}..<br />
- * Method may also store parms passed in for audit trail {@link org.apache.directory.fortress.core.model.FortEntity}.
- * <h4> This API will...</h4>
- * <ul>
- * <li> authenticate user password if trusted == false.
- * <li> perform <a href="http://www.openldap.org/">OpenLDAP</a> <a href="http://tools.ietf
- * .org/html/draft-behera-ldap-password-policy-10/">password policy evaluation</a>.
- * <li> fail for any user who is locked by OpenLDAP's policies {@link org.apache.directory.fortress.core.model.User#isLocked()},
- * regardless of trusted flag being set as parm on API.
- * <li> evaluate temporal {@link org.apache.directory.fortress.core.model.Constraint}(s) on {@link org.apache.directory.fortress.core.model.User},
- * {@link org.apache.directory.fortress.core.model.UserRole} and {@link org.apache.directory.fortress.core.model.UserAdminRole} entities.
- * <li> process selective role activations into User RBAC Session {@link User#roles}.
- * <li> check Dynamic Separation of Duties {@link org.apache.directory.fortress.core.impl.DSDChecker)} on {@link org.apache.directory.fortress.core.model.User#roles}.
- * <li> process selective administrative role activations {@link User#adminRoles}.
- * <li> return a {@link org.apache.directory.fortress.core.model.Session} containing {@link org.apache.directory.fortress.core.model.Session#getUser()},
- * {@link org.apache.directory.fortress.core.model.Session#getRoles()} and {@link org.apache.directory.fortress.core.model.Session#getAdminRoles()} if
- * everything checks out good.
- * <li> throw a checked exception that will be {@link org.apache.directory.fortress.core.SecurityException} or its derivation.
- * <li> throw a {@link SecurityException} for system failures.
- * <li> throw a {@link org.apache.directory.fortress.core.PasswordException} for authentication and password policy violations.
- * <li> throw a {@link org.apache.directory.fortress.core.ValidationException} for data validation errors.
- * <li> throw a {@link org.apache.directory.fortress.core.FinderException} if User id not found.
- * </ul>
- * <h4>
- * The function is valid if and only if:
- * </h4>
- * <ul>
- * <li> the user is a member of the USERS data set
- * <li> the password is supplied (unless trusted).
- * <li> the (optional) active role set is a subset of the roles authorized for that user.
- * </ul>
- * <h4>
- * The following attributes may be set when calling this method
- * </h4>
- * <ul>
- * <li> {@link org.apache.directory.fortress.core.model.User#userId} - required
- * <li> {@link org.apache.directory.fortress.core.model.User#password}
- * <li> {@link org.apache.directory.fortress.core.model.User#roles} contains a list of RBAC role names authorized for user and
- * targeted for activation within this session. Default is all authorized RBAC roles will be activated into this
- * Session.
- * <li> {@link org.apache.directory.fortress.core.model.User#adminRoles} contains a list of Admin role names authorized for user and
- * targeted for activation. Default is all authorized ARBAC roles will be activated into this Session.
- * <li> {@link User#props} collection of name value pairs collected on behalf of User during signon. For example
- * hostname:myservername or ip:192.168.1.99
- * </ul>
- * <h4>
- * Notes:
- * </h4>
- * <ul>
- * <li> roles that violate Dynamic Separation of Duty Relationships will not be activated into session.
- * <li> role activations will proceed in same order as supplied to User entity setter,
- * see {@link org.apache.directory.fortress.core.model.User#setRole}.
- * </ul>
- * </p>
- *
- * @param userId maps to {@link org.apache.directory.fortress.core.model.User#userId}.
- * @param password maps to {@link org.apache.directory.fortress.core.model.User#password}.
- * @return TcPrincipal which contains the User's RBAC Session data formatted into a java.security.Principal that
- * is used by Tomcat runtime.
- * @throws org.apache.directory.fortress.core.SecurityException
- * in the event of data validation failure, security policy violation or DAO error.
+ * {@inheritDoc}
*/
@Override
public TcPrincipal createSession( String userId, char[] password ) throws SecurityException
@@ -180,62 +110,8 @@
return createSession( user );
}
-
/**
- * Perform user authentication {@link User#password} and role activations.<br />
- * This method must be called once per user prior to calling other methods within this class.
- * The successful result is {@link org.apache.directory.fortress.core.model.Session} that contains target user's RBAC {@link User#roles} and Admin role {@link User#adminRoles}.<br />
- * In addition to checking user password validity it will apply configured password policy checks {@link org.apache.directory.fortress.core.model.User#pwPolicy}..<br />
- * Method may also store parms passed in for audit trail {@link org.apache.directory.fortress.core.model.FortEntity}.
- * <h4> This API will...</h4>
- * <ul>
- * <li> authenticate user password if trusted == false.
- * <li> perform <a href="http://www.openldap.org/">OpenLDAP</a> <a href="http://tools.ietf.org/html/draft-behera-ldap-password-policy-10/">password policy evaluation</a>.
- * <li> fail for any user who is locked by OpenLDAP's policies {@link org.apache.directory.fortress.core.model.User#isLocked()}, regardless of trusted flag being set as parm on API.
- * <li> evaluate temporal {@link org.apache.directory.fortress.core.model.Constraint}(s) on {@link User}, {@link org.apache.directory.fortress.core.model.UserRole} and {@link org.apache.directory.fortress.core.model.UserAdminRole} entities.
- * <li> process selective role activations into User RBAC Session {@link User#roles}.
- * <li> check Dynamic Separation of Duties {@link org.apache.directory.fortress.core.impl.DSDChecker} on {@link org.apache.directory.fortress.core.model.User#roles}.
- * <li> process selective administrative role activations {@link User#adminRoles}.
- * <li> return a {@link org.apache.directory.fortress.core.model.Session} containing {@link org.apache.directory.fortress.core.model.Session#getUser()}, {@link org.apache.directory.fortress.core.model.Session#getRoles()} and {@link org.apache.directory.fortress.core.model.Session#getAdminRoles()} if everything checks out good.
- * <li> throw a checked exception that will be {@link org.apache.directory.fortress.core.SecurityException} or its derivation.
- * <li> throw a {@link SecurityException} for system failures.
- * <li> throw a {@link org.apache.directory.fortress.core.PasswordException} for authentication and password policy violations.
- * <li> throw a {@link org.apache.directory.fortress.core.ValidationException} for data validation errors.
- * <li> throw a {@link org.apache.directory.fortress.core.FinderException} if User id not found.
- * </ul>
- * <h4>
- * The function is valid if and only if:
- * </h4>
- * <ul>
- * <li> the user is a member of the USERS data set
- * <li> the password is supplied (unless trusted).
- * <li> the (optional) active role set is a subset of the roles authorized for that user.
- * </ul>
- * <h4>
- * The following attributes may be set when calling this method
- * </h4>
- * <ul>
- * <li> {@link User#userId} - required
- * <li> {@link org.apache.directory.fortress.core.model.User#password}
- * <li> {@link org.apache.directory.fortress.core.model.User#roles} contains a list of RBAC role names authorized for user and targeted for activation within this session. Default is all authorized RBAC roles will be activated into this Session.
- * <li> {@link org.apache.directory.fortress.core.model.User#adminRoles} contains a list of Admin role names authorized for user and targeted for activation. Default is all authorized ARBAC roles will be activated into this Session.
- * <li> {@link User#props} collection of name value pairs collected on behalf of User during signon. For example hostname:myservername or ip:192.168.1.99
- * </ul>
- * <h4>
- * Notes:
- * </h4>
- * <ul>
- * <li> roles that violate Dynamic Separation of Duty Relationships will not be activated into session.
- * <li> role activations will proceed in same order as supplied to User entity setter, see {@link org.apache.directory.fortress.core.model.User#setRole}.
- * </ul>
- * </p>
- *
- * @param userId maps to {@link org.apache.directory.fortress.core.model.User#userId}.
- * @param password maps to {@link org.apache.directory.fortress.core.model.User#password}.
- * @param roles constains list of role names to activate.
- * @return TcPrincipal which contains the User's RBAC Session data formatted into a java.security.Principal that is used by Tomcat runtime.
- * @throws org.apache.directory.fortress.core.SecurityException
- * in the event of data validation failure, security policy violation or DAO error.
+ * {@inheritDoc}
*/
public TcPrincipal createSession( String userId, char[] password, List<String> roles ) throws SecurityException
{
@@ -253,13 +129,8 @@
return createSession( user );
}
-
/**
- * Utility function to call Fortress createSession, build the principal on behalf of caller.
- *
- * @param user
- * @return
- * @throws SecurityException
+ * {@inheritDoc}
*/
private TcPrincipal createSession( User user ) throws SecurityException
{
@@ -280,78 +151,7 @@
}
/**
- * Perform user authentication {@link org.apache.directory.fortress.core.model.User#password} and role activations.<br />
- * This method must be called once per user prior to calling other methods within this class.
- * The successful result is {@link org.apache.directory.fortress.core.model.Session} that contains target user's RBAC {@link
- * User#roles} and Admin role {@link User#adminRoles}.<br />
- * In addition to checking user password validity it will apply configured password policy checks {@link org.openldap
- * .fortress.rbac.User#pwPolicy}..<br />
- * Method may also store parms passed in for audit trail {@link org.apache.directory.fortress.core.model.FortEntity}.
- * <h4> This API will...</h4>
- * <ul>
- * <li> authenticate user password if trusted == false.
- * <li> perform <a href="http://www.openldap.org/">OpenLDAP</a> <a href="http://tools.ietf
- * .org/html/draft-behera-ldap-password-policy-10/">password policy evaluation</a>.
- * <li> fail for any user who is locked by OpenLDAP's policies {@link org.apache.directory.fortress.core.model.User#isLocked()},
- * regardless of trusted flag being set as parm on API.
- * <li> evaluate temporal {@link org.apache.directory.fortress.core.model.Constraint}(s) on {@link org.apache.directory.fortress.core.model.User},
- * {@link org.apache.directory.fortress.core.model.UserRole} and {@link org.apache.directory.fortress.core.model.UserAdminRole} entities.
- * <li> process selective role activations into User RBAC Session {@link User#roles}.
- * <li> check Dynamic Separation of Duties {@link org.apache.directory.fortress.core.impl.DSDChecker} on {@link org.apache.directory.fortress.core
- * .rbac.User#roles}.
- * <li> process selective administrative role activations {@link User#adminRoles}.
- * <li> return a {@link org.apache.directory.fortress.core.model.Session} containing {@link org.apache.directory.fortress.core.model.Session#getUser()},
- * {@link org.apache.directory.fortress.core.model.Session#getRoles()} and {@link org.apache.directory.fortress.core.model.Session#getAdminRoles()} if
- * everything checks out good.
- * <li> throw a checked exception that will be {@link org.apache.directory.fortress.core.SecurityException} or its derivation.
- * <li> throw a {@link SecurityException} for system failures.
- * <li> throw a {@link org.apache.directory.fortress.core.PasswordException} for authentication and password policy violations.
- * <li> throw a {@link org.apache.directory.fortress.core.ValidationException} for data validation errors.
- * <li> throw a {@link org.apache.directory.fortress.core.FinderException} if User id not found.
- * </ul>
- * <h4>
- * The function is valid if and only if:
- * </h4>
- * <ul>
- * <li> the user is a member of the USERS data set
- * <li> the password is supplied (unless trusted).
- * <li> the (optional) active role set is a subset of the roles authorized for that user.
- * </ul>
- * <h4>
- * The following attributes may be set when calling this method
- * </h4>
- * <ul>
- * <li> {@link org.apache.directory.fortress.core.model.User#userId} - required
- * <li> {@link org.apache.directory.fortress.core.model.User#password}
- * <li> {@link org.apache.directory.fortress.core.model.User#roles} contains a list of RBAC role names authorized for user and
- * targeted for activation within this session. Default is all authorized RBAC roles will be activated into this
- * Session.
- * <li> {@link org.apache.directory.fortress.core.model.User#adminRoles} contains a list of Admin role names authorized for user and
- * targeted for activation. Default is all authorized ARBAC roles will be activated into this Session.
- * <li> {@link org.apache.directory.fortress.core.model.User#props} collection of name value pairs collected on behalf of User during
- * signon. For example hostname:myservername or ip:192.168.1.99
- * </ul>
- * <h4>
- * Notes:
- * </h4>
- * <ul>
- * <li> roles that violate Dynamic Separation of Duty Relationships will not be activated into session.
- * <li> role activations will proceed in same order as supplied to User entity setter,
- * see {@link org.apache.directory.fortress.core.model.User#setRole}.
- * </ul>
- * </p>
- *
- * @param user Contains {@link org.apache.directory.fortress.core.model.User#userId}, {@link org.apache.directory.fortress.core.model.User#password}
- * (optional if {@code isTrusted} is 'true'), optional {@link org.apache.directory.fortress.core.model.User#roles},
- * optional {@link org.apache.directory.fortress.core.model.User#adminRoles}
- * @param isTrusted if true password is not required.
- * @return Session object will contain authentication result code {@link org.apache.directory.fortress.core.model.Session#errorId},
- * RBAC role activations {@link org.apache.directory.fortress.core.model.Session#getRoles()}, Admin Role activations {@link org.openldap
- * .fortress.rbac.Session#getAdminRoles()},OpenLDAP pw policy codes {@link org.apache.directory.fortress.core.model
- * .Session#warningId}, {@link org.apache.directory.fortress.core.model.Session#expirationSeconds},
- * {@link org.apache.directory.fortress.core.model.Session#graceLogins} and more.
- * @throws org.apache.directory.fortress.core.SecurityException
- * in the event of data validation failure, security policy violation or DAO error.
+ * {@inheritDoc}
*/
@Override
public Session createSession( User user, boolean isTrusted ) throws SecurityException
@@ -361,17 +161,8 @@
return accessMgr.createSession( user, isTrusted );
}
-
/**
- * Determine if given Role is contained within User's Tomcat Principal object. This method does not need to hit
- * the ldap server as the User's activated Roles are loaded into {@link org.apache.directory.fortress.realm.tomcat
- * .TcPrincipal#setContext(java.util.HashMap)}
- *
- * @param principal Contains User's Tomcat RBAC Session data that includes activated Roles.
- * @param roleName Maps to {@link org.apache.directory.fortress.core.model.Role#name}.
- * @return True if Role is found in TcPrincipal, false otherwise.
- * @throws org.apache.directory.fortress.core.SecurityException
- * data validation failure or system error..
+ * {@inheritDoc}
*/
@Override
public boolean hasRole( Principal principal, String roleName ) throws SecurityException
@@ -416,14 +207,8 @@
return result;
}
-
/**
- * Method reads Role entity from the role container in directory.
- *
- * @param roleName maps to {@link org.apache.directory.fortress.core.model.Role#name}, to be read.
- * @return Role entity that corresponds with role name.
- * @throws org.apache.directory.fortress.core.SecurityException
- * will be thrown if role not found or system error occurs.
+ * {@inheritDoc}
*/
@Override
public Role readRole( String roleName ) throws SecurityException
@@ -431,31 +216,17 @@
return reviewMgr.readRole( new Role( roleName ) );
}
-
/**
- * Search for Roles assigned to given User.
- *
- * @param searchString Maps to {@link org.apache.directory.fortress.core.model.User#userId}.
- * @param limit controls the size of ldap result set returned.
- * @return List of type String containing the {@link org.apache.directory.fortress.core.model.Role#name} of all assigned Roles.
- * @throws org.apache.directory.fortress.core.SecurityException
- * in the event of data validation failure or DAO error.
+ * {@inheritDoc}
*/
@Override
- public List<String> searchRoles( String searchString, int limit ) throws SecurityException
+ public List<String> searchRoles(String searchString, int limit ) throws SecurityException
{
return reviewMgr.findRoles( searchString, limit );
}
-
/**
- * Method returns matching User entity that is contained within the people container in the directory.
- *
- * @param userId maps to {@link org.apache.directory.fortress.core.model.User#userId} that matches record in the directory. userId
- * is globally unique in
- * people container.
- * @return entity containing matching user data.
- * @throws SecurityException if record not found or system error occurs.
+ * {@inheritDoc}
*/
@Override
public User readUser( String userId ) throws SecurityException
@@ -463,36 +234,17 @@
return reviewMgr.readUser( new User( userId ) );
}
-
/**
- * Return a list of type String of all users in the people container that match the userId field passed in User
- * entity.
- * This method is used by the Websphere sentry component. The max number of returned users may be set by the
- * integer limit arg.
- *
- * @param searchString contains all or some leading chars that correspond to users stored in the directory.
- * @param limit integer value sets the max returned records.
- * @return List of type String containing matching userIds.
- * @throws SecurityException in the event of system error.
+ * {@inheritDoc}
*/
@Override
- public List<String> searchUsers( String searchString, int limit ) throws SecurityException
+ public List<String> searchUsers(String searchString, int limit ) throws SecurityException
{
return reviewMgr.findUsers( new User( searchString ), limit );
}
-
/**
- * This function returns the set of users assigned to a given role. The function is valid if and
- * only if the role is a member of the ROLES data set.
- * The max number of users returned is constrained by limit argument.
- * This method is used by the Websphere sentry component. This method does NOT use hierarchical rbac.
- *
- * @param roleName maps to {@link org.apache.directory.fortress.core.model.Role#name} of Role entity assigned to user.
- * @param limit integer value sets the max returned records.
- * @return List of type String containing userIds assigned to a particular role.
- * @throws org.apache.directory.fortress.core.SecurityException
- * in the event of data validation or system error.
+ * {@inheritDoc}
*/
@Override
public List<String> assignedUsers( String roleName, int limit ) throws SecurityException
@@ -500,14 +252,8 @@
return reviewMgr.assignedUsers( new Role( roleName ), limit );
}
-
/**
- * This function returns the set of roles authorized for a given user. The function is valid if
- * and only if the user is a member of the USERS data set.
- *
- * @param userId maps to {@link org.apache.directory.fortress.core.model.User#userId} matching User entity stored in the directory.
- * @return Set of type String containing the roles assigned and roles inherited.
- * @throws SecurityException If user not found or system error occurs.
+ * {@inheritDoc}
*/
@Override
public List<String> authorizedRoles( String userId ) throws SecurityException
@@ -527,7 +273,6 @@
return list;
}
-
/**
* Utility to write any object into a Base64 string. Used by this class to serialize {@link TcPrincipal} object to be returned by its toString method..
@@ -558,12 +303,8 @@
return szRetVal;
}
-
/**
- * This utility method deserializes java.security.Principal to Fortress RBAC session object.
- *
- * @param str contains String to deserialize
- * @return deserialization target object
+ * {@inheritDoc}
*/
public Session deserialize( String str ) throws SecurityException
{
@@ -591,4 +332,15 @@
throw new SecurityException( org.apache.directory.fortress.realm.GlobalIds.CONTEXT_DESERIALIZATION_FAILED_CLASS_NOT_FOUND, "deserialize caught ClassNotFoundException:" + e, e );
}
}
-}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final void setContextId(String contextId)
+ {
+ this.contextId = contextId;
+ accessMgr.setContextId( contextId );
+ reviewMgr.setContextId( contextId );
+ }
+}
\ No newline at end of file
diff --git a/impl/src/main/java/org/apache/directory/fortress/realm/tomcat/TC7AccessMgrFascade.java b/impl/src/main/java/org/apache/directory/fortress/realm/tomcat/TC7AccessMgrFascade.java
deleted file mode 100644
index 430e132..0000000
--- a/impl/src/main/java/org/apache/directory/fortress/realm/tomcat/TC7AccessMgrFascade.java
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.directory.fortress.realm.tomcat;
-
-import org.apache.catalina.LifecycleException;
-import org.apache.catalina.Wrapper;
-import org.apache.catalina.realm.RealmBase;
-
-import java.security.Principal;
-import java.util.logging.Logger;
-
-/**
- * This class extends the Tomcat 7 and beyond RealmBase class and provides Java EE security services within the Tomcat container.
- * This class is a "proxy" for the {@link org.apache.directory.fortress.realm.tomcat.TcAccessMgrImpl} class which isolates dependencies from the Tomcat
- * runtime environment by loading the implementation on a URLClassLoader.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-public class TC7AccessMgrFascade extends RealmBase
-{
- private static final String CLS_NM = TC7AccessMgrFascade.class.getName();
- private static final Logger LOG = Logger.getLogger( CLS_NM );
- private static final String REALM_IMPL = "org.apache.directory.fortress.realm.tomcat.TcAccessMgrImpl";
- private static final String REALM_CLASSPATH = "REALM_CLASSPATH";
- private static final String JBOSS_AGENT = "jboss";
- private String container = "Catalina7";
- private String defaultRoles;
- private String realmClasspath;
- private TcAccessMgr realm = new TcAccessMgrImpl();
-
- /**
- * Gets the info attribute of the TcAccessMgrProxy object
- *
- * @return The info value
- */
- @Override
- public String getInfo()
- {
- return info;
- }
-
-
- /**
- * Perform user authentication and evaluate password policies.
- *
- * @param userId Contains the userid of the user signing on.
- * @param password Contains the user's password.
- * @return Principal whic * This method will load the Fortress Tomcat implementation on a URL classloader. Methods on the implementation are
- * wrapped by methods on this class and are accessed via the {@code realm} instance variable of this class.
- */
- @Override
- public Principal authenticate( String userId, String password )
- {
- if ( realm == null )
- {
- throw new RuntimeException( CLS_NM + "authenticate detected Fortress Tomcat7 Realm not initialized correctly. Check your Fortress Realm configuration" );
- }
-
- return realm.authenticate( userId, password.toCharArray()) ;
- }
-
-
- /**
- * Determine if given Role is contained within User's Tomcat Principal object. This method does not need to hit
- * the ldap server as the User's activated Roles are loaded into {@link org.apache.directory.fortress.realm.TcPrincipal#setContext(java.util.HashMap)}
- *
- * @param principal Contains User's Tomcat RBAC Session data that includes activated Roles.
- * @param role Maps to {@code org.apache.directory.fortress.core.model.Role#name}.
- * @return True if Role is found in TcPrincipal, false otherwise.
- */
- @Override
- public boolean hasRole( Wrapper wrapper, Principal principal, String role )
- {
- if ( realm == null )
- {
- throw new RuntimeException( CLS_NM + "authenticate detected Fortress Tomcat7 Realm not initialized correctly. Check your Fortress Realm configuration" );
- }
-
- return realm.hasRole( principal, role );
- }
-
-
- /**
- * Gets the name attribute of the TcAccessMgrProxy object
- *
- * @return The name value
- */
- @Override
- protected String getName()
- {
- return ( CLS_NM );
- }
-
-
- /**
- * Gets the password attribute of the TcAccessMgrProxy object
- *
- * @param username Description of the Parameter
- * @return The password value
- */
- @Override
- protected String getPassword( String username )
- {
- return null;
- }
-
-
- /**
- * Gets the principal attribute of the TcAccessMgrProxy object
- *
- * @param username Description of the Parameter
- * @return The principal value
- */
- @Override
- protected Principal getPrincipal( String username )
- {
- return null;
- }
-
-
- /**
- * Prepare for the beginning of active use of the public methods of this
- * component and implement the requirements of
- * {@link org.apache.catalina.util.LifecycleBase#startInternal()}.
- *
- * @throws LifecycleException if this component detects a fatal error
- * that prevents this component from being used
- */
- @Override
- protected void startInternal() throws LifecycleException
- {
- super.startInternal();
- }
-
-
- /**
- * Gracefully terminate the active use of the public methods of this
- * component and implement the requirements of
- * {@link org.apache.catalina.util.LifecycleBase#stopInternal()}.
- *
- * @throws LifecycleException if this component detects a fatal error
- * that needs to be reported
- */
- @Override
- protected void stopInternal() throws LifecycleException
- {
-
- // Perform normal superclass finalization
- super.stopInternal();
-
- // Release reference to our sentry impl
- realm = null;
-
- }
-
-
- /**
- * Gets the containerType attribute of the TcAccessMgrProxy object
- *
- * @return The containerType value
- */
- public String getContainerType()
- {
- return container;
- }
-
-
- /**
- * Sets the containerType attribute of the TcAccessMgrProxy object
- *
- * @param container The new containerType value
- */
- public void setContainerType( String container )
- {
- LOG.info( CLS_NM + ".setContainerType <" + container + ">" );
- this.container = container;
- }
-
-
- /**
- * Gets the realmClasspath attribute of the TcAccessMgrProxy object
- *
- * @return The realmClasspath value
- */
- public String getRealmClasspath()
- {
- LOG.info( CLS_NM + ".getRealmClasspath <" + realmClasspath + ">" );
- return realmClasspath;
- }
-
-
- /**
- * Sets the realmClasspath attribute of the TcAccessMgrProxy object
- *
- * @param rCpth The new realmClasspath value
- */
- public void setRealmClasspath( String rCpth )
- {
- LOG.info( CLS_NM + ".setRealmClasspath <" + rCpth + ">" );
- this.realmClasspath = rCpth;
- }
-
- /**
- * Gets the defaultRoles attribute of the TcAccessMgrProxy object. When set, it will be passed into all subsequent calls to Fortress createSession.
- *
- * @return String containing comma delimited list of role names.
- */
- public String getDefaultRoles()
- {
- LOG.info( CLS_NM + ".getDefaultRoles <" + defaultRoles + ">" );
- return defaultRoles;
- }
-
- /**
- * Sets the defaultRoles attribute of the TcAccessMgrProxy object. When set, it will be passed into all subsequent calls to Fortress createSession.
- *
- * @param defaultRoles containing comma delimited list of role names.
- */
- public void setDefaultRoles( String defaultRoles )
- {
- LOG.info( CLS_NM + ".setDefaultRoles <" + defaultRoles + ">" );
- this.defaultRoles = defaultRoles;
- }
-}
\ No newline at end of file
diff --git a/impl/src/main/java/org/apache/directory/fortress/realm/tomcat/TcAccessMgrImpl.java b/impl/src/main/java/org/apache/directory/fortress/realm/tomcat/TcAccessMgrImpl.java
index 1fab25c..6f260a7 100644
--- a/impl/src/main/java/org/apache/directory/fortress/realm/tomcat/TcAccessMgrImpl.java
+++ b/impl/src/main/java/org/apache/directory/fortress/realm/tomcat/TcAccessMgrImpl.java
@@ -47,6 +47,7 @@
private J2eePolicyMgr j2eeMgr;
// If this field gets set, use for all subsequent calls to authenticate:
private List<String> defaultRoles;
+ private String contextId;
/**
* Constructor for the TcAccessMgrImpl object
@@ -55,7 +56,7 @@
{
try
{
- j2eeMgr = J2eePolicyMgrFactory.createInstance();
+ j2eeMgr = J2eePolicyMgrFactory.createInstance( );
LOG.info( "{} constructor <{}>", CLS_NM, incrementCtr() );
}
catch ( SecurityException se )
@@ -71,19 +72,17 @@
{
return count++;
}
-
+
/**
- * Perform user authentication and evaluate password policies.
- *
- * @param userId Contains the userid of the user signing on.
- * @param password Contains the user's password.
- * @return Principal which contains the Fortress RBAC session data.
+ * {@inheritDoc}
*/
+ @Override
public Principal authenticate( String userId, char[] password )
{
TcPrincipal principal = null;
-
+
+ System.out.println("BREAK1");
try
{
// If a 'default.roles' property set in config, user them
@@ -106,29 +105,28 @@
return principal;
}
-
/**
- * Determine if given Role is contained within User's Tomcat Principal object. This method does not need to hit
- * the ldap server as the User's activated Roles are loaded into {@link TcPrincipal#setContext(java.util.HashMap)}
- *
- * @param principal Contains User's Tomcat RBAC Session data that includes activated Roles.
- * @param roleName Maps to {@code org.apache.directory.fortress.core.model.Role#name}.
- * @return True if Role is found in TcPrincipal, false otherwise.
+ * {@inheritDoc}
*/
+ @Override
public boolean hasRole( Principal principal, String roleName )
{
boolean result = false;
String userId = principal.getName();
-
+
+ System.out.println("BREAK2 user:" + userId + ", role" + roleName);
try
{
if ( j2eeMgr.hasRole( principal, roleName ) )
{
+ System.out.println("BREAK3 user:" + userId + ", role" + roleName);
+
LOG.debug( "{}.hasRole userId [{}], role[{}], successful", CLS_NM, principal.getName(), roleName );
result = true;
}
else
{
+ System.out.println("BREAK4 user:" + userId + ", role" + roleName);
LOG.debug( "{}.hasRole userId [{}], role[{}], failed", CLS_NM, principal.getName(), roleName );
}
}
@@ -137,15 +135,14 @@
LOG.warn( "{}.hasRole userId <{}> role <{}> caught SecurityException= {}", CLS_NM, userId, roleName, se);
}
+ System.out.println("BREAK5 user:" + userId + ", role" + roleName);
return result;
}
/**
- * When the 'defaultRoles' parameter is set on realm proxy config (e.g. in server.xml or context.xml) it will be used to pass into
- * createSession calls into Fortress. This will scope the roles to be considered for activation to this particular set.
- *
- * @param szDefaultRoles contains a String containing comma delimited roles names.
+ * {@inheritDoc}
*/
+ @Override
public void setDefaultRoles( String szDefaultRoles )
{
if( StringUtils.isNotEmpty( szDefaultRoles ) )
@@ -154,4 +151,15 @@
LOG.info( "DEFAULT ROLES: {}", defaultRoles );
}
}
-}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setContextId( String contextId )
+ {
+ this.contextId = contextId;
+ j2eeMgr.setContextId( contextId );
+ LOG.info( "CONTEXT ID: {}", contextId );
+ }
+}
\ No newline at end of file
diff --git a/proxy/src/main/java/org/apache/directory/fortress/realm/tomcat/Tc7AccessMgrProxy.java b/proxy/src/main/java/org/apache/directory/fortress/realm/tomcat/Tc7AccessMgrProxy.java
index 4c6ad05..0580f6a 100644
--- a/proxy/src/main/java/org/apache/directory/fortress/realm/tomcat/Tc7AccessMgrProxy.java
+++ b/proxy/src/main/java/org/apache/directory/fortress/realm/tomcat/Tc7AccessMgrProxy.java
@@ -41,13 +41,14 @@
public class Tc7AccessMgrProxy extends RealmBase
{
private static final String CLS_NM = Tc7AccessMgrProxy.class.getName();
- private static final Logger LOG = Logger.getLogger(CLS_NM);
+ private static final Logger LOG = Logger.getLogger( CLS_NM );
private static final String REALM_IMPL = "org.apache.directory.fortress.realm.tomcat.TcAccessMgrImpl";
private static final String REALM_CLASSPATH = "REALM_CLASSPATH";
private static final String JBOSS_AGENT = "jboss";
private String CONTAINER = "Catalina7";
private String defaultRoles;
private String realmClasspath;
+ private String contextId;
private TcAccessMgr realm;
/**
@@ -90,7 +91,8 @@
Class<?> sc = ucl.loadClass( REALM_IMPL );
realm = (TcAccessMgr) sc.newInstance();
realm.setDefaultRoles( defaultRoles );
- LOG.info( CLS_NM + " J2EE Tomcat7 policy agent initialization successful" );
+ realm.setContextId( contextId );
+ LOG.info( CLS_NM + " J2EE Tomcat7 policy agent, contextId: " + contextId + ", defaultRoles: " + defaultRoles );
}
catch ( ClassNotFoundException e )
{
@@ -320,4 +322,26 @@
LOG.info( CLS_NM + ".setDefaultRoles <" + defaultRoles + ">" );
this.defaultRoles = defaultRoles;
}
+
+ /**
+ * Gets the contextId attribute of the TcAccessMgrProxy object. When set, it will be used as tenant id within the fortress manager apis.
+ *
+ * @return String containing comma delimited list of role names.
+ */
+ public String getContextId()
+ {
+ LOG.info( CLS_NM + ".getContextId <" + contextId + ">" );
+ return contextId;
+ }
+
+ /**
+ * Sets the contextId attribute of the TcAccessMgrProxy object. When set, it will be used as tenant id within the fortress manager apis.
+ *
+ * @param contextId containing the id of instance.
+ */
+ public void setContextId(String contextId)
+ {
+ LOG.info( CLS_NM + ".setContextId <" + contextId + ">" );
+ this.contextId = contextId;
+ }
}
\ No newline at end of file
diff --git a/proxy/src/main/java/org/apache/directory/fortress/realm/tomcat/TcAccessMgr.java b/proxy/src/main/java/org/apache/directory/fortress/realm/tomcat/TcAccessMgr.java
index 4f9d055..19da26e 100644
--- a/proxy/src/main/java/org/apache/directory/fortress/realm/tomcat/TcAccessMgr.java
+++ b/proxy/src/main/java/org/apache/directory/fortress/realm/tomcat/TcAccessMgr.java
@@ -57,4 +57,13 @@
* @param roles contains a String containing comma delimited roles names.
*/
void setDefaultRoles( String roles );
+
+
+ /**
+ * When the 'contextId' parameter is set on realm proxy config (e.g. in server.xml or context.xml) it will be used to pass into
+ * fortress core apis as tenantId.
+ *
+ * @param contextId contains a String containing the tenantId for the operations.
+ */
+ public void setContextId( String contextId );
}
\ No newline at end of file