[jboss-cvs] Picketbox SVN: r226 - in trunk/security-jboss-sx/jbosssx/src: main/java/org/jboss/security/mapping/providers and 4 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Wed Jun 15 11:31:14 EDT 2011
Author: mmoyses
Date: 2011-06-15 11:31:14 -0400 (Wed, 15 Jun 2011)
New Revision: 226
Added:
trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/LdapUsersLoginModule.java
trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/PropertiesUsersLoginModule.java
trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/SimpleUsersLoginModule.java
trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/
trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/AbstractRolesMappingProvider.java
trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/DatabaseRolesMappingProvider.java
trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/LdapRolesMappingProvider.java
trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/PropertiesRolesMappingProvider.java
trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/SecurityActions.java
trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/SimpleRolesMappingProvider.java
trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/Util.java
Modified:
trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/AbstractServerLoginModule.java
trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/DatabaseServerLoginModule.java
trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/LdapExtLoginModule.java
trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/SecurityActions.java
trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/UsernamePasswordLoginModule.java
trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/Util.java
trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/plugins/TransactionManagerLocator.java
trunk/security-jboss-sx/jbosssx/src/test/java/org/jboss/test/authentication/JBossSecuritySubjectFactoryUnitTestCase.java
trunk/security-jboss-sx/jbosssx/src/test/java/org/jboss/test/authentication/jaas/LoginModulesUnitTestCase.java
Log:
Separate authentication from role mapping in the login modules
Modified: trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/AbstractServerLoginModule.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/AbstractServerLoginModule.java 2011-05-26 18:23:11 UTC (rev 225)
+++ trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/AbstractServerLoginModule.java 2011-06-15 15:31:14 UTC (rev 226)
@@ -216,6 +216,15 @@
Set<Principal> principals = subject.getPrincipals();
Principal identity = getIdentity();
principals.add(identity);
+ // add the CallerPrincipal group
+ Group callerGroup = getCallerPrincipalGroup(principals);
+ if (callerGroup == null)
+ {
+ callerGroup = new SimpleGroup(SecurityConstants.CALLER_PRINCIPAL_GROUP);
+ callerGroup.addMember(identity);
+ principals.add(callerGroup);
+ }
+ // add other role groups
Group[] roleSets = getRoleSets();
for(int g = 0; g < roleSets.length; g ++)
{
@@ -263,6 +272,9 @@
Principal identity = getIdentity();
Set<Principal> principals = subject.getPrincipals();
principals.remove(identity);
+ Group callerGroup = getCallerPrincipalGroup(principals);
+ if (callerGroup != null)
+ principals.remove(callerGroup);
// Remove any added Groups...
return true;
}
@@ -350,4 +362,22 @@
}
return p;
}
+
+ protected Group getCallerPrincipalGroup(Set<Principal> principals)
+ {
+ Group callerGroup = null;
+ for (Principal principal : principals)
+ {
+ if (principal instanceof Group)
+ {
+ Group group = Group.class.cast(principal);
+ if (group.getName().equals(SecurityConstants.CALLER_PRINCIPAL_GROUP))
+ {
+ callerGroup = group;
+ break;
+ }
+ }
+ }
+ return callerGroup;
+ }
}
\ No newline at end of file
Modified: trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/DatabaseServerLoginModule.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/DatabaseServerLoginModule.java 2011-05-26 18:23:11 UTC (rev 225)
+++ trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/DatabaseServerLoginModule.java 2011-06-15 15:31:14 UTC (rev 226)
@@ -75,7 +75,7 @@
/** The sql query to obtain the user password */
protected String principalsQuery = "select Password from Principals where PrincipalID=?";
/** The sql query to obtain the user roles */
- protected String rolesQuery = "select Role, RoleGroup from Roles where PrincipalID=?";
+ protected String rolesQuery;
/** Whether to suspend resume transactions during database operations */
protected boolean suspendResume = true;
@@ -114,7 +114,8 @@
{
log.trace("DatabaseServerLoginModule, dsJndiName="+dsJndiName);
log.trace("principalsQuery="+principalsQuery);
- log.trace("rolesQuery="+rolesQuery);
+ if (rolesQuery != null)
+ log.trace("rolesQuery="+rolesQuery);
log.trace("suspendResume="+suspendResume);
}
//Get the Transaction Manager JNDI Name
@@ -255,12 +256,16 @@
*/
protected Group[] getRoleSets() throws LoginException
{
- String username = getUsername();
- if (log.isTraceEnabled())
- log.trace("getRoleSets using rolesQuery: "+rolesQuery+", username: "+username);
- Group[] roleSets = Util.getRoleSets(username, dsJndiName, rolesQuery, this,
- suspendResume);
- return roleSets;
+ if (rolesQuery != null)
+ {
+ String username = getUsername();
+ if (log.isTraceEnabled())
+ log.trace("getRoleSets using rolesQuery: "+rolesQuery+", username: "+username);
+ Group[] roleSets = Util.getRoleSets(username, dsJndiName, rolesQuery, this,
+ suspendResume);
+ return roleSets;
+ }
+ return new Group[0];
}
/** A hook to allow subclasses to convert a password from the database
Modified: trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/LdapExtLoginModule.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/LdapExtLoginModule.java 2011-05-26 18:23:11 UTC (rev 225)
+++ trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/LdapExtLoginModule.java 2011-06-15 15:31:14 UTC (rev 226)
@@ -461,9 +461,7 @@
{
SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
- constraints.setReturningAttributes(new String[0]);
constraints.setTimeLimit(searchTimeLimit);
-
String attrList[] = {distinguishedNameAttribute};
constraints.setReturningAttributes(attrList);
@@ -657,6 +655,7 @@
Properties tmp = new Properties();
tmp.putAll(env);
tmp.setProperty(Context.SECURITY_CREDENTIALS, "***");
+ tmp.setProperty(BIND_CREDENTIAL, "***");
log.trace("Logging into LDAP server, env=" + tmp.toString());
}
}
Added: trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/LdapUsersLoginModule.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/LdapUsersLoginModule.java (rev 0)
+++ trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/LdapUsersLoginModule.java 2011-06-15 15:31:14 UTC (rev 226)
@@ -0,0 +1,338 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2011, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.security.auth.spi;
+
+import java.security.acl.Group;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Map.Entry;
+
+import javax.naming.Context;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import javax.naming.ldap.InitialLdapContext;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginException;
+
+import org.jboss.security.Util;
+
+/**
+ * A login module to authenticate users using a LDAP server.
+ *
+ * @author <a href="mmoyses at redhat.com">Marcus Moyses</a>
+ * @author Andy Oliver
+ * @author Scott.Stark at jboss.org
+ */
+public class LdapUsersLoginModule extends UsernamePasswordLoginModule
+{
+ private static final String BIND_DN = "bindDN";
+
+ private static final String BIND_CREDENTIAL = "bindCredential";
+
+ private static final String BASE_CTX_DN = "baseCtxDN";
+
+ private static final String BASE_FILTER_OPT = "baseFilter";
+
+ private static final String SEARCH_TIME_LIMIT_OPT = "searchTimeLimit";
+
+ private static final String SEARCH_SCOPE_OPT = "searchScope";
+
+ private static final String DISTINGUISHED_NAME_ATTRIBUTE_OPT = "distinguishedNameAttribute";
+
+ private static final String PARSE_USERNAME = "parseUsername";
+
+ private static final String USERNAME_BEGIN_STRING = "usernameBeginString";
+
+ private static final String USERNAME_END_STRING = "usernameEndString";
+
+ private static final String ALLOW_EMPTY_PASSWORDS = "allowEmptyPasswords";
+
+ protected String bindDN;
+
+ protected String bindCredential;
+
+ protected String baseDN;
+
+ protected String baseFilter;
+
+ protected int searchTimeLimit = 10000;
+
+ protected int searchScope = SearchControls.SUBTREE_SCOPE;
+
+ protected String distinguishedNameAttribute;
+
+ protected boolean parseUsername;
+
+ protected String usernameBeginString;
+
+ protected String usernameEndString;
+
+ protected boolean allowEmptyPasswords;
+
+ @Override
+ protected String getUsersPassword() throws LoginException
+ {
+ return "";
+ }
+
+ @Override
+ protected Group[] getRoleSets() throws LoginException
+ {
+ return new Group[0];
+ }
+
+ @Override
+ protected String getUsername()
+ {
+ String username = super.getUsername();
+ if (parseUsername)
+ {
+ int beginIndex = 0;
+ if (usernameBeginString != null && !usernameBeginString.equals(""))
+ beginIndex = username.indexOf(usernameBeginString) + usernameBeginString.length();
+ if (beginIndex == -1) // not allowed. reset
+ beginIndex = 0;
+ int endIndex = username.length();
+ if (usernameEndString != null && !usernameEndString.equals(""))
+ endIndex = username.substring(beginIndex).indexOf(usernameEndString);
+ if (endIndex == -1) // not allowed. reset
+ endIndex = username.length();
+ else
+ endIndex += beginIndex;
+ username = username.substring(beginIndex, endIndex);
+ }
+ return username;
+ }
+
+ @Override
+ public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState,
+ Map<String, ?> options)
+ {
+ super.initialize(subject, callbackHandler, sharedState, options);
+ trace = log.isTraceEnabled();
+ bindDN = (String) options.get(BIND_DN);
+ bindCredential = (String) options.get(BIND_CREDENTIAL);
+ if ((bindCredential != null) && bindCredential.startsWith("{EXT}"))
+ {
+ try
+ {
+ bindCredential = new String(Util.loadPassword(bindCredential));
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("Unable to decode bindCredential", e);
+ }
+ }
+ baseDN = (String) options.get(BASE_CTX_DN);
+ baseFilter = (String) options.get(BASE_FILTER_OPT);
+ String timeLimit = (String) options.get(SEARCH_TIME_LIMIT_OPT);
+ if (timeLimit != null)
+ {
+ try
+ {
+ searchTimeLimit = Integer.parseInt(timeLimit);
+ }
+ catch (NumberFormatException e)
+ {
+ if (trace)
+ log.trace("Failed to parse: " + timeLimit + ", using searchTimeLimit=" + searchTimeLimit, e);
+ }
+ }
+ String scope = (String) options.get(SEARCH_SCOPE_OPT);
+ if ("OBJECT_SCOPE".equalsIgnoreCase(scope))
+ searchScope = SearchControls.OBJECT_SCOPE;
+ else if ("ONELEVEL_SCOPE".equalsIgnoreCase(scope))
+ searchScope = SearchControls.ONELEVEL_SCOPE;
+ if ("SUBTREE_SCOPE".equalsIgnoreCase(scope))
+ searchScope = SearchControls.SUBTREE_SCOPE;
+
+ distinguishedNameAttribute = (String) options.get(DISTINGUISHED_NAME_ATTRIBUTE_OPT);
+ if (distinguishedNameAttribute == null)
+ distinguishedNameAttribute = "distinguishedName";
+ allowEmptyPasswords = Boolean.valueOf((String) options.get(ALLOW_EMPTY_PASSWORDS));
+
+ parseUsername = Boolean.valueOf((String) options.get(PARSE_USERNAME));
+ if (parseUsername)
+ {
+ usernameBeginString = (String) options.get(USERNAME_BEGIN_STRING);
+ usernameEndString = (String) options.get(USERNAME_END_STRING);
+ }
+ }
+
+ @Override
+ protected boolean validatePassword(String inputPassword, String expectedPassword)
+ {
+ boolean isValid = false;
+ if (inputPassword != null)
+ {
+ // See if this is an empty password that should be disallowed
+ if (inputPassword.length() == 0)
+ {
+ if (allowEmptyPasswords == false)
+ {
+ if(trace)
+ log.trace("Rejecting empty password due to allowEmptyPasswords");
+ return false;
+ }
+ }
+
+ try
+ {
+ // Validate the password by trying to create an initial context
+ String username = getUsername();
+ isValid = createLdapInitContext(username, inputPassword);
+ }
+ catch (Throwable e)
+ {
+ super.setValidateError(e);
+ }
+ }
+ return isValid;
+ }
+
+ /**
+ * Bind to the LDAP server for authentication
+ */
+ private boolean createLdapInitContext(String username, Object credential) throws Exception
+ {
+ // Get the admin context for searching
+ InitialLdapContext ctx = null;
+ ClassLoader currentTCCL = SecurityActions.getContextClassLoader();
+ try
+ {
+ if (currentTCCL != null)
+ SecurityActions.setContextClassLoader(null);
+ ctx = constructInitialLdapContext(bindDN, bindCredential);
+ // Validate the user by binding against the userDN
+ bindDNAuthentication(ctx, username, credential, baseDN, baseFilter);
+ }
+ finally
+ {
+ if (ctx != null)
+ ctx.close();
+ if (currentTCCL != null)
+ SecurityActions.setContextClassLoader(currentTCCL);
+ }
+ return true;
+ }
+
+ private InitialLdapContext constructInitialLdapContext(String dn, Object credential) throws NamingException
+ {
+ Properties env = new Properties();
+ Iterator iter = options.entrySet().iterator();
+ while (iter.hasNext())
+ {
+ Entry entry = (Entry) iter.next();
+ env.put(entry.getKey(), entry.getValue());
+ }
+
+ // Set defaults for key values if they are missing
+ String factoryName = env.getProperty(Context.INITIAL_CONTEXT_FACTORY);
+ if (factoryName == null)
+ {
+ factoryName = "com.sun.jndi.ldap.LdapCtxFactory";
+ env.setProperty(Context.INITIAL_CONTEXT_FACTORY, factoryName);
+ }
+ String authType = env.getProperty(Context.SECURITY_AUTHENTICATION);
+ if (authType == null)
+ env.setProperty(Context.SECURITY_AUTHENTICATION, "simple");
+ String protocol = env.getProperty(Context.SECURITY_PROTOCOL);
+ String providerURL = (String) options.get(Context.PROVIDER_URL);
+ if (providerURL == null)
+ providerURL = "ldap://localhost:" + ((protocol != null && protocol.equals("ssl")) ? "636" : "389");
+
+ env.setProperty(Context.PROVIDER_URL, providerURL);
+ // JBAS-3555, allow anonymous login with no bindDN and bindCredential
+ if (dn != null)
+ env.setProperty(Context.SECURITY_PRINCIPAL, dn);
+ if (credential != null)
+ env.put(Context.SECURITY_CREDENTIALS, credential);
+ traceLdapEnv(env);
+ return new InitialLdapContext(env, null);
+ }
+
+ private void traceLdapEnv(Properties env)
+ {
+ if (trace)
+ {
+ Properties tmp = new Properties();
+ tmp.putAll(env);
+ tmp.setProperty(Context.SECURITY_CREDENTIALS, "***");
+ tmp.setProperty(BIND_CREDENTIAL, "***");
+ log.trace("Logging into LDAP server, env=" + tmp.toString());
+ }
+ }
+
+ protected String bindDNAuthentication(InitialLdapContext ctx, String user, Object credential, String baseDN,
+ String filter) throws NamingException
+ {
+ SearchControls constraints = new SearchControls();
+ constraints.setSearchScope(searchScope);
+ constraints.setTimeLimit(searchTimeLimit);
+ String attrList[] = {distinguishedNameAttribute};
+ constraints.setReturningAttributes(attrList);
+
+ NamingEnumeration<SearchResult> results = null;
+
+ Object[] filterArgs = {user};
+ results = ctx.search(baseDN, filter, filterArgs, constraints);
+ if (!results.hasMore())
+ {
+ results.close();
+ throw new NamingException("Search of baseDN(" + baseDN + ") found no matches");
+ }
+
+ SearchResult sr = results.next();
+ String name = sr.getName();
+ String userDN = null;
+ Attributes attrs = sr.getAttributes();
+ if (attrs != null)
+ {
+ Attribute dn = attrs.get(distinguishedNameAttribute);
+ if (dn != null)
+ {
+ userDN = (String) dn.get();
+ }
+ }
+ if (userDN == null)
+ {
+ if (sr.isRelative())
+ userDN = name + ("".equals(baseDN) ? "" : "," + baseDN);
+ else
+ throw new NamingException("Can't follow referal for authentication: " + name);
+ }
+
+ results.close();
+ results = null;
+ // Bind as the user dn to authenticate the user
+ InitialLdapContext userCtx = constructInitialLdapContext(userDN, credential);
+ userCtx.close();
+
+ return userDN;
+ }
+}
Added: trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/PropertiesUsersLoginModule.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/PropertiesUsersLoginModule.java (rev 0)
+++ trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/PropertiesUsersLoginModule.java 2011-06-15 15:31:14 UTC (rev 226)
@@ -0,0 +1,52 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2011, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.security.auth.spi;
+
+import java.io.IOException;
+import java.security.acl.Group;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.security.auth.login.LoginException;
+
+/**
+ * A {@code LoginModule} that uses a properties file to store username and password for authentication.
+ * No roles are mapped.
+ *
+ * @author <a href="mmoyses at redhat.com">Marcus Moyses</a>
+ */
+public class PropertiesUsersLoginModule extends UsersRolesLoginModule
+{
+
+ @Override
+ protected Group[] getRoleSets() throws LoginException
+ {
+ return new Group[0];
+ }
+
+ @Override
+ protected Properties createRoles(Map<String, ?> options) throws IOException
+ {
+ return new Properties();
+ }
+
+}
Modified: trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/SecurityActions.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/SecurityActions.java 2011-05-26 18:23:11 UTC (rev 225)
+++ trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/SecurityActions.java 2011-06-15 15:31:14 UTC (rev 226)
@@ -83,21 +83,34 @@
}
});
}
-
- static Class<?> loadClass(final String name) throws PrivilegedActionException
+
+ static Class<?> loadClass(final String name) throws PrivilegedActionException
{
return AccessController.doPrivileged(new PrivilegedExceptionAction<Class<?>>()
{
- public Class<?> run() throws PrivilegedActionException
+ public Class<?> run() throws ClassNotFoundException
{
- try
+ ClassLoader[] cls = new ClassLoader[] {
+ getContextClassLoader(), // User defined classes
+ SecurityActions.class.getClassLoader(), // PB classes (not always on TCCL [modular env])
+ ClassLoader.getSystemClassLoader() }; // System loader, usually has app class path
+
+ ClassNotFoundException e = null;
+ for (ClassLoader cl : cls)
{
- return getContextClassLoader().loadClass(name);
+ if (cl == null)
+ continue;
+
+ try
+ {
+ return cl.loadClass(name);
+ }
+ catch (ClassNotFoundException ce)
+ {
+ e = ce;
+ }
}
- catch ( Exception e)
- {
- throw new PrivilegedActionException(e);
- }
+ throw e != null ? e : new ClassNotFoundException(name);
}
});
}
Added: trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/SimpleUsersLoginModule.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/SimpleUsersLoginModule.java (rev 0)
+++ trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/SimpleUsersLoginModule.java 2011-06-15 15:31:14 UTC (rev 226)
@@ -0,0 +1,87 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2011, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.security.auth.spi;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.jboss.security.SecurityConstants;
+
+/**
+ * A {@code LoginModule} that stores username and password as options.
+ *
+ * @author <a href="mmoyses at redhat.com">Marcus Moyses</a>
+ */
+public class SimpleUsersLoginModule extends PropertiesUsersLoginModule
+{
+
+ protected static Set<String> invalidProperties = new HashSet<String>();
+
+ // adding valid properties' keys from super classes
+ {
+ invalidProperties.add("usersProperties");
+ invalidProperties.add("defaultUsersProperties");
+ invalidProperties.add("rolesProperties");
+ invalidProperties.add("defaultRolesProperties");
+ invalidProperties.add("roleGroupSeperator");
+ invalidProperties.add("digestCallback");
+ invalidProperties.add("storeDigestCallback");
+ invalidProperties.add("legacyCreatePasswordHash");
+ invalidProperties.add("inputValidator");
+ invalidProperties.add("hashAlgorithm");
+ invalidProperties.add("hashEncoding");
+ invalidProperties.add("hashCharset");
+ invalidProperties.add("hashStorePassword");
+ invalidProperties.add("hashUserPassword");
+ invalidProperties.add("ignorePasswordCase");
+ invalidProperties.add("throwValidateError");
+ invalidProperties.add(SecurityConstants.SECURITY_DOMAIN_OPTION);
+ invalidProperties.add("password-stacking");
+ invalidProperties.add("principalClass");
+ invalidProperties.add("unauthenticatedIdentity");
+ }
+
+ @Override
+ protected Properties createUsers(Map<String, ?> options) throws IOException
+ {
+ Properties properties = new Properties();
+ for (Entry<String, ?> entry : options.entrySet())
+ {
+ String key = entry.getKey();
+ Object value = entry.getValue();
+ if (value != null && isValidEntry(key))
+ properties.put(key, value);
+ }
+
+ return properties;
+ }
+
+ protected boolean isValidEntry(String key)
+ {
+ return !invalidProperties.contains(key);
+ }
+
+}
Modified: trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/UsernamePasswordLoginModule.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/UsernamePasswordLoginModule.java 2011-05-26 18:23:11 UTC (rev 225)
+++ trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/UsernamePasswordLoginModule.java 2011-06-15 15:31:14 UTC (rev 226)
@@ -412,8 +412,7 @@
{
try
{
- ClassLoader loader = SecurityActions.getContextClassLoader();
- Class<?> callbackClass = loader.loadClass(callbackClassName);
+ Class<?> callbackClass = SecurityActions.loadClass(callbackClassName);
callback = (DigestCallback) callbackClass.newInstance();
if( log.isTraceEnabled() )
log.trace("Created DigestCallback: "+callback);
Modified: trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/Util.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/Util.java 2011-05-26 18:23:11 UTC (rev 225)
+++ trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/auth/spi/Util.java 2011-06-15 15:31:14 UTC (rev 226)
@@ -268,7 +268,7 @@
}
else
{
- throw new IOException("Properties file " + propertiesName + " not avilable");
+ throw new IOException("Properties file " + propertiesName + " not available");
}
if (trace)
log.trace("Loaded properties, users="+bundle.keySet());
@@ -290,33 +290,52 @@
* @exception java.io.IOException thrown if the properties file cannot be found
* or loaded
*/
- static Properties loadProperties(String propertiesName, Logger log)
- throws IOException
- {
+ static Properties loadProperties(String propertiesName, Logger log) throws IOException
+ {
boolean trace = log.isTraceEnabled();
-
- ClassLoader loader = SecurityActions.getContextClassLoader();
+
+ Properties bundle = null;
+ ClassLoader loader = SecurityActions.getContextClassLoader();
URL url = null;
// First check for local visibility via a URLClassLoader.findResource
- if( loader instanceof URLClassLoader )
+ if (loader instanceof URLClassLoader)
{
- URLClassLoader ucl = (URLClassLoader) loader;
- url = SecurityActions.findResource(ucl,propertiesName);
- if(trace)
- log.trace("findResource: "+url);
- }
- if( url == null )
+ URLClassLoader ucl = (URLClassLoader) loader;
+ url = SecurityActions.findResource(ucl, propertiesName);
+ if (trace)
+ log.trace("findResource: " + url);
+ }
+ // Do a general resource search
+ if (url == null)
+ {
url = loader.getResource(propertiesName);
- if( url == null)
+ if (url == null)
+ {
+ try
+ {
+ url = new URL(propertiesName);
+ }
+ catch (MalformedURLException mue)
+ {
+ if (trace)
+ log.trace("Failed to open properties as URL", mue);
+ File tmp = new File(propertiesName);
+ if (tmp.exists())
+ url = tmp.toURI().toURL();
+ }
+ }
+ }
+ if (url == null)
{
- url = new URL(propertiesName);
+ String msg = "No properties file: " + propertiesName + " found";
+ throw new IOException(msg);
}
- if(trace)
- log.trace("Properties file=" + url );
-
- Properties bundle = new Properties();
- if( url != null )
+ if (trace)
+ log.trace("Properties file=" + url);
+ Properties defaults = new Properties();
+ bundle = new Properties(defaults);
+ if (url != null)
{
InputStream is = null;
try
@@ -325,8 +344,8 @@
}
catch (PrivilegedActionException e)
{
- if(trace)
- log.trace("open stream error:", e);
+ if (trace)
+ log.trace("Open stream error", e);
throw new IOException(e.getLocalizedMessage());
}
if (is != null)
@@ -338,7 +357,8 @@
{
throw new IOException("Properties file " + propertiesName + " not available");
}
- log.debug("Loaded properties, users="+bundle.keySet());
+ if (trace)
+ log.trace("Loaded properties, users=" + bundle.keySet());
}
return bundle;
Added: trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/AbstractRolesMappingProvider.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/AbstractRolesMappingProvider.java (rev 0)
+++ trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/AbstractRolesMappingProvider.java 2011-06-15 15:31:14 UTC (rev 226)
@@ -0,0 +1,88 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2011, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.security.mapping.providers.role;
+
+import java.security.Principal;
+import java.security.acl.Group;
+import java.util.Enumeration;
+import java.util.Map;
+import java.util.Set;
+
+import org.jboss.logging.Logger;
+import org.jboss.security.SecurityConstants;
+import org.jboss.security.identity.RoleGroup;
+import org.jboss.security.mapping.MappingProvider;
+import org.jboss.security.mapping.MappingResult;
+
+/**
+ * Abstract class for Role mapping providers
+ * @author <a href="mmoyses at redhat.com">Marcus Moyses</a>
+ */
+public abstract class AbstractRolesMappingProvider implements MappingProvider<RoleGroup>
+{
+ protected Logger log;
+
+ protected MappingResult<RoleGroup> result;
+
+ @Override
+ public boolean supports(Class<?> p)
+ {
+ if (RoleGroup.class.isAssignableFrom(p))
+ return true;
+
+ return false;
+ }
+
+ @Override
+ public void setMappingResult(MappingResult<RoleGroup> result)
+ {
+ this.result = result;
+ }
+
+ protected Principal getCallerPrincipal(Map<String, Object> map)
+ {
+ Principal principal = (Principal) map.get(SecurityConstants.PRINCIPAL_IDENTIFIER);
+ Principal callerPrincipal = null;
+ if (principal == null)
+ {
+ @SuppressWarnings("unchecked")
+ Set<Principal> principals = (Set<Principal>) map.get(SecurityConstants.PRINCIPALS_SET_IDENTIFIER);
+ if (principals != null && !principals.isEmpty())
+ {
+ for (Principal p : principals) {
+ if (!(p instanceof Group) && principal == null) {
+ principal = p;
+ }
+ if (p instanceof Group) {
+ Group g = Group.class.cast(p);
+ if (g.getName().equals(SecurityConstants.CALLER_PRINCIPAL_GROUP) && callerPrincipal == null) {
+ Enumeration<? extends Principal> e = g.members();
+ if (e.hasMoreElements())
+ callerPrincipal = e.nextElement();
+ }
+ }
+ }
+ }
+ }
+ return callerPrincipal == null ? principal : callerPrincipal;
+ }
+}
\ No newline at end of file
Added: trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/DatabaseRolesMappingProvider.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/DatabaseRolesMappingProvider.java (rev 0)
+++ trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/DatabaseRolesMappingProvider.java 2011-06-15 15:31:14 UTC (rev 226)
@@ -0,0 +1,112 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2011, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.security.mapping.providers.role;
+
+import java.security.Principal;
+import java.util.Map;
+
+import javax.naming.NamingException;
+import javax.transaction.TransactionManager;
+
+import org.jboss.logging.Logger;
+import org.jboss.security.identity.RoleGroup;
+import org.jboss.security.plugins.TransactionManagerLocator;
+
+/**
+ * A {@code MappingProvider} that reads roles from a database.
+ *
+ * rolesQuery option should be a prepared statement equivalent to
+ * "select RoleName from Roles where User=?"
+ *
+ * @author <a href="mmoyses at redhat.com">Marcus Moyses</a>
+ */
+public class DatabaseRolesMappingProvider extends AbstractRolesMappingProvider
+{
+
+ protected String dsJndiName;
+
+ protected String rolesQuery;
+
+ protected boolean suspendResume = true;
+
+ protected String TX_MGR_JNDI_NAME = "java:/TransactionManager";
+
+ protected TransactionManager tm = null;
+
+ @Override
+ public void init(Map<String, Object> options)
+ {
+ log = Logger.getLogger(getClass());
+
+ if (options != null)
+ {
+ dsJndiName = (String) options.get("dsJndiName");
+ if (dsJndiName == null)
+ throw new IllegalArgumentException("Datasource JNDI name can't be null");
+ rolesQuery = (String) options.get("rolesQuery");
+ if (rolesQuery == null)
+ throw new IllegalArgumentException("Prepared statement can't be null");
+ String option = (String) options.get("suspendResume");
+ if (option != null)
+ suspendResume = Boolean.valueOf(option.toString()).booleanValue();
+
+ // Get the Transaction Manager JNDI Name
+ option = (String) options.get("transactionManagerJndiName");
+ if (option != null)
+ TX_MGR_JNDI_NAME = option;
+ try
+ {
+ if (suspendResume)
+ tm = getTransactionManager();
+ }
+ catch (NamingException e)
+ {
+ throw new RuntimeException("Unable to get Transaction Manager", e);
+ }
+ }
+ }
+
+ @Override
+ public void performMapping(Map<String, Object> map, RoleGroup mappedObject)
+ {
+ if (map == null || map.isEmpty())
+ throw new IllegalArgumentException("Context Map is null or empty");
+
+ //Obtain the principal to roles mapping
+ Principal principal = getCallerPrincipal(map);
+
+ if (principal != null && rolesQuery != null)
+ {
+ String username = principal.getName();
+ Util.addRolesToGroup(username, mappedObject, dsJndiName, rolesQuery, log, suspendResume, tm);
+ result.setMappedObject(mappedObject);
+ }
+
+ }
+
+ protected TransactionManager getTransactionManager() throws NamingException
+ {
+ TransactionManagerLocator tml = new TransactionManagerLocator();
+ return tml.getTM(this.TX_MGR_JNDI_NAME);
+ }
+
+}
Added: trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/LdapRolesMappingProvider.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/LdapRolesMappingProvider.java (rev 0)
+++ trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/LdapRolesMappingProvider.java 2011-06-15 15:31:14 UTC (rev 226)
@@ -0,0 +1,396 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2011, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.security.mapping.providers.role;
+
+import java.security.Principal;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.Map.Entry;
+
+import javax.naming.Context;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import javax.naming.ldap.InitialLdapContext;
+
+import org.jboss.logging.Logger;
+import org.jboss.security.Util;
+import org.jboss.security.identity.RoleGroup;
+import org.jboss.security.identity.plugins.SimpleRole;
+
+/**
+ * A mapping provider that assigns roles to an user using a LDAP server to search for the roles.
+ *
+ * @author <a href="mmoyses at redhat.com">Marcus Moyses</a>
+ * @author Andy Oliver
+ * @author Scott.Stark at jboss.org
+ */
+public class LdapRolesMappingProvider extends AbstractRolesMappingProvider
+{
+ private static final String BIND_DN = "bindDN";
+
+ private static final String BIND_CREDENTIAL = "bindCredential";
+
+ private static final String ROLES_CTX_DN_OPT = "rolesCtxDN";
+
+ private static final String ROLE_ATTRIBUTE_ID_OPT = "roleAttributeID";
+
+ private static final String ROLE_ATTRIBUTE_IS_DN_OPT = "roleAttributeIsDN";
+
+ private static final String ROLE_NAME_ATTRIBUTE_ID_OPT = "roleNameAttributeID";
+
+ private static final String PARSE_ROLE_NAME_FROM_DN_OPT = "parseRoleNameFromDN";
+
+ private static final String ROLE_FILTER_OPT = "roleFilter";
+
+ private static final String ROLE_RECURSION = "roleRecursion";
+
+ private static final String SEARCH_TIME_LIMIT_OPT = "searchTimeLimit";
+
+ private static final String SEARCH_SCOPE_OPT = "searchScope";
+
+ protected String bindDN;
+
+ protected String bindCredential;
+
+ protected String rolesCtxDN;
+
+ protected String roleFilter;
+
+ protected String roleAttributeID;
+
+ protected String roleNameAttributeID;
+
+ protected boolean roleAttributeIsDN;
+
+ protected boolean parseRoleNameFromDN;
+
+ protected int recursion = 0;
+
+ protected int searchTimeLimit = 10000;
+
+ protected int searchScope = SearchControls.SUBTREE_SCOPE;
+
+ protected Map<String, Object> options;
+
+ protected boolean trace;
+
+ @Override
+ public void init(Map<String, Object> options)
+ {
+ log = Logger.getLogger(getClass());
+ trace = log.isTraceEnabled();
+
+ if (options != null)
+ {
+ this.options = options;
+ bindDN = (String) options.get(BIND_DN);
+ bindCredential = (String) options.get(BIND_CREDENTIAL);
+ if ((bindCredential != null) && bindCredential.startsWith("{EXT}"))
+ {
+ try
+ {
+ bindCredential = new String(Util.loadPassword(bindCredential));
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("Unable to decode bindCredential", e);
+ }
+ }
+ roleFilter = (String) options.get(ROLE_FILTER_OPT);
+ roleAttributeID = (String) options.get(ROLE_ATTRIBUTE_ID_OPT);
+ if (roleAttributeID == null)
+ roleAttributeID = "role";
+ // Is user's role attribute a DN or the role name
+ String roleAttributeIsDNOption = (String) options.get(ROLE_ATTRIBUTE_IS_DN_OPT);
+ roleAttributeIsDN = Boolean.valueOf(roleAttributeIsDNOption).booleanValue();
+ roleNameAttributeID = (String) options.get(ROLE_NAME_ATTRIBUTE_ID_OPT);
+ if (roleNameAttributeID == null)
+ roleNameAttributeID = "name";
+
+ //JBAS-4619:Parse Role Name from DN
+ String parseRoleNameFromDNOption = (String) options.get(PARSE_ROLE_NAME_FROM_DN_OPT);
+ parseRoleNameFromDN = Boolean.valueOf(parseRoleNameFromDNOption).booleanValue();
+
+ rolesCtxDN = (String) options.get(ROLES_CTX_DN_OPT);
+ String strRecursion = (String) options.get(ROLE_RECURSION);
+ try
+ {
+ recursion = Integer.parseInt(strRecursion);
+ }
+ catch (Exception e)
+ {
+ if (trace)
+ log.trace("Failed to parse: " + strRecursion + ", disabling recursion", e);
+ // its okay for this to be 0 as this just disables recursion
+ recursion = 0;
+ }
+ String timeLimit = (String) options.get(SEARCH_TIME_LIMIT_OPT);
+ if (timeLimit != null)
+ {
+ try
+ {
+ searchTimeLimit = Integer.parseInt(timeLimit);
+ }
+ catch (NumberFormatException e)
+ {
+ if (trace)
+ log.trace("Failed to parse: " + timeLimit + ", using searchTimeLimit=" + searchTimeLimit, e);
+ }
+ }
+ String scope = (String) options.get(SEARCH_SCOPE_OPT);
+ if ("OBJECT_SCOPE".equalsIgnoreCase(scope))
+ searchScope = SearchControls.OBJECT_SCOPE;
+ else if ("ONELEVEL_SCOPE".equalsIgnoreCase(scope))
+ searchScope = SearchControls.ONELEVEL_SCOPE;
+ if ("SUBTREE_SCOPE".equalsIgnoreCase(scope))
+ searchScope = SearchControls.SUBTREE_SCOPE;
+ }
+ }
+
+ @Override
+ public void performMapping(Map<String, Object> map, RoleGroup mappedObject)
+ {
+ if (map == null || map.isEmpty())
+ throw new IllegalArgumentException("Context Map is null or empty");
+
+ //Obtain the principal to roles mapping
+ Principal principal = getCallerPrincipal(map);
+
+ if (principal != null)
+ {
+ // Get the admin context for searching
+ InitialLdapContext ctx = null;
+ ClassLoader currentTCCL = SecurityActions.getContextClassLoader();
+ try
+ {
+ if (currentTCCL != null)
+ SecurityActions.setContextClassLoader(null);
+ ctx = constructInitialLdapContext(bindDN, bindCredential);
+
+ // Query for roles matching the role filter
+ SearchControls constraints = new SearchControls();
+ constraints.setSearchScope(searchScope);
+ constraints.setReturningAttributes(new String[0]);
+ constraints.setTimeLimit(searchTimeLimit);
+ rolesSearch(ctx, constraints, principal.getName(), recursion, 0, mappedObject);
+ }
+ catch (NamingException ne)
+ {
+ log.error("Error connecting to LDAP server", ne);
+ }
+ finally
+ {
+ if (ctx != null)
+ {
+ try
+ {
+ ctx.close();
+ }
+ catch (NamingException ne)
+ {
+ log.error("Error closing context", ne);
+ }
+ }
+ if (currentTCCL != null)
+ SecurityActions.setContextClassLoader(currentTCCL);
+ }
+ }
+ }
+
+ protected InitialLdapContext constructInitialLdapContext(String dn, Object credential) throws NamingException
+ {
+ Properties env = new Properties();
+ Iterator<Entry<String, Object>> iter = options.entrySet().iterator();
+ while (iter.hasNext())
+ {
+ Entry<String, Object> entry = iter.next();
+ env.put(entry.getKey(), entry.getValue());
+ }
+
+ // Set defaults for key values if they are missing
+ String factoryName = env.getProperty(Context.INITIAL_CONTEXT_FACTORY);
+ if (factoryName == null)
+ {
+ factoryName = "com.sun.jndi.ldap.LdapCtxFactory";
+ env.setProperty(Context.INITIAL_CONTEXT_FACTORY, factoryName);
+ }
+ String authType = env.getProperty(Context.SECURITY_AUTHENTICATION);
+ if (authType == null)
+ env.setProperty(Context.SECURITY_AUTHENTICATION, "simple");
+ String protocol = env.getProperty(Context.SECURITY_PROTOCOL);
+ String providerURL = (String) options.get(Context.PROVIDER_URL);
+ if (providerURL == null)
+ providerURL = "ldap://localhost:" + ((protocol != null && protocol.equals("ssl")) ? "636" : "389");
+
+ env.setProperty(Context.PROVIDER_URL, providerURL);
+ // JBAS-3555, allow anonymous login with no bindDN and bindCredential
+ if (dn != null)
+ env.setProperty(Context.SECURITY_PRINCIPAL, dn);
+ if (credential != null)
+ env.put(Context.SECURITY_CREDENTIALS, credential);
+ traceLdapEnv(env);
+ return new InitialLdapContext(env, null);
+ }
+
+ private void traceLdapEnv(Properties env)
+ {
+ if (trace)
+ {
+ Properties tmp = new Properties();
+ tmp.putAll(env);
+ tmp.setProperty(Context.SECURITY_CREDENTIALS, "***");
+ tmp.setProperty(BIND_CREDENTIAL, "***");
+ log.trace("Logging into LDAP server, env=" + tmp.toString());
+ }
+ }
+
+ protected void rolesSearch(InitialLdapContext ctx, SearchControls constraints, String user, int recursionMax,
+ int nesting, RoleGroup roleGroup) throws NamingException
+ {
+ Object[] filterArgs = {user};
+ NamingEnumeration<SearchResult> results = ctx.search(rolesCtxDN, roleFilter, filterArgs, constraints);
+ try
+ {
+ while (results.hasMore())
+ {
+ SearchResult sr = results.next();
+ String dn = canonicalize(sr.getName());
+
+ // Query the context for the roleDN values
+ String[] attrNames = {roleAttributeID};
+ Attributes result = ctx.getAttributes(dn, attrNames);
+ if (result != null && result.size() > 0)
+ {
+ Attribute roles = result.get(roleAttributeID);
+ for (int n = 0; n < roles.size(); n++)
+ {
+ String roleName = (String) roles.get(n);
+ if (roleAttributeIsDN && parseRoleNameFromDN)
+ {
+ parseRole(roleName, roleGroup);
+ }
+ else if (roleAttributeIsDN)
+ {
+ // Query the roleDN location for the value of roleNameAttributeID
+ String roleDN = roleName;
+ String[] returnAttribute = {roleNameAttributeID};
+ if (trace)
+ log.trace("Using roleDN: " + roleDN);
+ try
+ {
+ Attributes result2 = ctx.getAttributes(roleDN, returnAttribute);
+ Attribute roles2 = result2.get(roleNameAttributeID);
+ if (roles2 != null)
+ {
+ for (int m = 0; m < roles2.size(); m++)
+ {
+ roleName = (String) roles2.get(m);
+ addRole(roleName, roleGroup);
+ }
+ }
+ }
+ catch (NamingException e)
+ {
+ if (trace)
+ log.trace("Failed to query roleNameAttrName", e);
+ }
+ }
+ else
+ {
+ // The role attribute value is the role name
+ addRole(roleName, roleGroup);
+ }
+ }
+ }
+
+ if (nesting < recursionMax)
+ {
+ rolesSearch(ctx, constraints, user, recursionMax, nesting + 1, roleGroup);
+ }
+ }
+ }
+ finally
+ {
+ if (results != null)
+ results.close();
+ }
+ }
+
+ //JBAS-3438 : Handle "/" correctly
+ private String canonicalize(String searchResult)
+ {
+ String result = searchResult;
+ int len = searchResult.length();
+
+ String appendRolesCtxDN = "" + ("".equals(rolesCtxDN) ? "" : "," + rolesCtxDN);
+ if (searchResult.endsWith("\""))
+ {
+ result = searchResult.substring(0, len - 1) + appendRolesCtxDN + "\"";
+ }
+ else
+ {
+ result = searchResult + appendRolesCtxDN;
+ }
+ return result;
+ }
+
+ private void addRole(String roleName, RoleGroup roleGroup)
+ {
+ if (roleName != null)
+ {
+ try
+ {
+ SimpleRole role = new SimpleRole(roleName);
+ if (trace)
+ log.trace("Assign user to role " + roleName);
+ roleGroup.addRole(role);
+ }
+ catch (Exception e)
+ {
+ if (trace)
+ log.debug("Failed to create principal: " + roleName, e);
+ }
+ }
+ }
+
+ private void parseRole(String dn, RoleGroup roleGroup)
+ {
+ StringTokenizer st = new StringTokenizer(dn, ",");
+ while (st != null && st.hasMoreTokens())
+ {
+ String keyVal = st.nextToken();
+ if (keyVal.indexOf(roleNameAttributeID) > -1)
+ {
+ StringTokenizer kst = new StringTokenizer(keyVal, "=");
+ kst.nextToken();
+ addRole(kst.nextToken(), roleGroup);
+ }
+ }
+ }
+
+}
Added: trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/PropertiesRolesMappingProvider.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/PropertiesRolesMappingProvider.java (rev 0)
+++ trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/PropertiesRolesMappingProvider.java 2011-06-15 15:31:14 UTC (rev 226)
@@ -0,0 +1,96 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2011, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.security.mapping.providers.role;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.util.Map;
+import java.util.Properties;
+
+import org.jboss.logging.Logger;
+import org.jboss.security.identity.RoleGroup;
+import org.jboss.util.StringPropertyReplacer;
+
+/**
+ * A {@code MappingProvider} that reads roles from a properties file in the format
+ *
+ * <p>
+ * username=role1,role2,...
+ * </p>
+ *
+ * and adds those roles to the security context for authorization purposes.
+ *
+ * @author <a href="mmoyses at redhat.com">Marcus Moyses</a>
+ */
+public class PropertiesRolesMappingProvider extends AbstractRolesMappingProvider
+{
+
+ protected String rolesRsrcName = "roles.properties";
+
+ protected Properties roles;
+
+ @Override
+ public void init(Map<String, Object> options)
+ {
+ log = Logger.getLogger(getClass());
+
+ if (options != null)
+ {
+ String option = (String) options.get("rolesProperties");
+ if (option != null)
+ rolesRsrcName = StringPropertyReplacer.replaceProperties(option);
+
+ // read properties file
+ try
+ {
+ roles = loadRoles();
+ }
+ catch (IOException ioe)
+ {
+ throw new IllegalStateException("Error loading roles properties file", ioe);
+ }
+ }
+ }
+
+ @Override
+ public void performMapping(Map<String, Object> map, RoleGroup mappedObject)
+ {
+ if (map == null || map.isEmpty())
+ throw new IllegalArgumentException("Context Map is null or empty");
+
+ //Obtain the principal to roles mapping
+ Principal principal = getCallerPrincipal(map);
+
+ if (principal != null)
+ {
+ String username = principal.getName();
+ Util.addRolesToGroup(username, mappedObject, roles, log);
+ result.setMappedObject(mappedObject);
+ }
+ }
+
+ protected Properties loadRoles() throws IOException
+ {
+ return Util.loadProperties(rolesRsrcName, log);
+ }
+
+}
Added: trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/SecurityActions.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/SecurityActions.java (rev 0)
+++ trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/SecurityActions.java 2011-06-15 15:31:14 UTC (rev 226)
@@ -0,0 +1,103 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.security.mapping.providers.role;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+/**
+ * Privileged Blocks
+ * @author Anil.Saldhana at redhat.com
+ * @since Sep 26, 2007
+ * @version $Revision$
+ */
+class SecurityActions
+{
+ static ClassLoader getContextClassLoader()
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
+ {
+ public ClassLoader run()
+ {
+ return Thread.currentThread().getContextClassLoader();
+ }
+ });
+ }
+
+ static Void setContextClassLoader(final ClassLoader cl)
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<Void>()
+ {
+ public Void run()
+ {
+ Thread.currentThread().setContextClassLoader(cl);
+ return null;
+ }
+ });
+ }
+
+ static URL findResource(final URLClassLoader cl, final String name)
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<URL>()
+ {
+ public URL run()
+ {
+ return cl.findResource(name);
+ }
+ });
+ }
+
+ static InputStream openStream(final URL url) throws PrivilegedActionException
+ {
+ return AccessController.doPrivileged(new PrivilegedExceptionAction<InputStream>()
+ {
+ public InputStream run() throws IOException
+ {
+ return url.openStream();
+ }
+ });
+ }
+
+ static Class<?> loadClass(final String name) throws PrivilegedActionException
+ {
+ return AccessController.doPrivileged(new PrivilegedExceptionAction<Class<?>>()
+ {
+ public Class<?> run() throws PrivilegedActionException
+ {
+ try
+ {
+ return getContextClassLoader().loadClass(name);
+ }
+ catch (Exception e)
+ {
+ throw new PrivilegedActionException(e);
+ }
+ }
+ });
+ }
+}
\ No newline at end of file
Added: trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/SimpleRolesMappingProvider.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/SimpleRolesMappingProvider.java (rev 0)
+++ trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/SimpleRolesMappingProvider.java 2011-06-15 15:31:14 UTC (rev 226)
@@ -0,0 +1,90 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2011, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.security.mapping.providers.role;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Properties;
+
+import org.jboss.logging.Logger;
+
+/**
+ * A simple {@code MappingProvider} that reads roles from the options map.
+ * The option key is the username to assign roles to and the option value is
+ * the comma separated role names to assign to the user.
+ *
+ * @author <a href="mmoyses at redhat.com">Marcus Moyses</a>
+ */
+public class SimpleRolesMappingProvider extends PropertiesRolesMappingProvider
+{
+ protected Map<String, Object> options;
+
+ @Override
+ public void init(Map<String, Object> options)
+ {
+ log = Logger.getLogger(getClass());
+
+ this.options = options;
+
+ if (options != null)
+ {
+ try
+ {
+ roles = loadRoles();
+ }
+ catch (IOException ioe)
+ {
+ throw new IllegalStateException("Error loading roles from options", ioe);
+ }
+ }
+ }
+
+ /**
+ * Load roles from options map
+ */
+ @Override
+ protected Properties loadRoles() throws IOException
+ {
+ roles = new Properties();
+ for (Map.Entry<String, Object> entry : options.entrySet())
+ {
+ String key = entry.getKey();
+ if (isValidEntry(key))
+ roles.put(key, entry.getValue());
+ }
+
+ return roles;
+ }
+
+ /**
+ * Removes entries that are valid options for super classes
+ *
+ * @param key entry key
+ * @return true if entry is valid, false otherwise
+ */
+ protected boolean isValidEntry(String key)
+ {
+ if (key.equals("rolesProperties"))
+ return false;
+ return true;
+ }
+}
Added: trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/Util.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/Util.java (rev 0)
+++ trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/mapping/providers/role/Util.java 2011-06-15 15:31:14 UTC (rev 226)
@@ -0,0 +1,300 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.security.mapping.providers.role;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.security.PrivilegedActionException;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.sql.DataSource;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.jboss.logging.Logger;
+import org.jboss.security.identity.RoleGroup;
+import org.jboss.security.identity.plugins.SimpleRole;
+
+/**
+ * Utility class for this package.
+ *
+ * @author <a href="mmoyses at redhat.com">Marcus Moyses</a>
+ */
+public class Util
+{
+
+ /**
+ * Utility method which loads the given properties file and returns a
+ * Properties object containing the key,value pairs in that file.
+ * The properties files should be in the class path as this method looks
+ * to the thread context class loader (TCL) to locate the resource. If the
+ * TCL is a URLClassLoader the findResource(String) method is first tried.
+ * If this fails or the TCL is not a URLClassLoader getResource(String) is
+ * tried.
+ * @param propertiesName - the name of the properties file resource
+ * @param log - the logger used for trace level messages
+ * @return the loaded properties file if found
+ * @exception java.io.IOException thrown if the properties file cannot be found
+ * or loaded
+ */
+ static Properties loadProperties(String propertiesName, Logger log) throws IOException
+ {
+ boolean trace = log.isTraceEnabled();
+
+ Properties bundle = null;
+ ClassLoader loader = SecurityActions.getContextClassLoader();
+ URL url = null;
+ // First check for local visibility via a URLClassLoader.findResource
+ if (loader instanceof URLClassLoader)
+ {
+ URLClassLoader ucl = (URLClassLoader) loader;
+ url = SecurityActions.findResource(ucl, propertiesName);
+ if (log.isTraceEnabled())
+ log.trace("findResource: " + url);
+ }
+ // Do a general resource search
+ if (url == null)
+ url = loader.getResource(propertiesName);
+ if (url == null) {
+ try {
+ url = new URL(propertiesName);
+ } catch (MalformedURLException mue) {
+ if (trace)
+ log.trace("Failed to open properties as URL", mue);
+ File tmp = new File(propertiesName);
+ if (tmp.exists())
+ url = tmp.toURI().toURL();
+ }
+ }
+ if (url == null)
+ {
+ String msg = "No properties file " + propertiesName + " found";
+ throw new IOException(msg);
+ }
+
+ if (log.isTraceEnabled())
+ log.trace("Properties file=" + url);
+ Properties defaults = new Properties();
+ bundle = new Properties(defaults);
+ InputStream is = null;
+ try
+ {
+ is = SecurityActions.openStream(url);
+ }
+ catch (PrivilegedActionException e)
+ {
+ if (trace)
+ log.trace("Open stream error", e);
+ throw new IOException(e.getLocalizedMessage());
+ }
+ if (is != null)
+ {
+ bundle.load(is);
+ is.close();
+ }
+ else
+ {
+ throw new IOException("Properties file " + propertiesName + " not available");
+ }
+ if (trace)
+ log.debug("Loaded properties, keySet=" + bundle.keySet());
+
+ return bundle;
+ }
+
+ /**
+ * Create the set of roles the user belongs to by parsing the roles.properties
+ * data for username=role1,role2,...
+ *
+ * @param username - name of user
+ * @param roleGroup - group containing the user's roles
+ * @param roles - the Properties containing the user=roles mappings
+ * @param log - logger
+ * @return Group[] containing the sets of roles
+ */
+ static void addRolesToGroup(String username, RoleGroup roleGroup, Properties roles, Logger log)
+ {
+ boolean trace = log.isTraceEnabled();
+ String[] roleNames = null;
+ if (roles.containsKey(username))
+ {
+ String value = roles.getProperty(username);
+ if (trace)
+ log.trace("Adding to RoleGroup: " + value);
+ roleNames = parseRoles(value);
+ }
+ if (roleNames != null)
+ {
+ for (int i = 0; i < roleNames.length; i++)
+ {
+ roleGroup.addRole(new SimpleRole(roleNames[i]));
+ }
+ }
+ }
+
+ /**
+ * Parse the comma delimited roles names given by value
+ *
+ * @param roles - the comma delimited role names.
+ */
+ static String[] parseRoles(String roles)
+ {
+ return roles.split(",");
+ }
+
+ /**
+ * Create the set of roles the user belongs to by querying a database
+ *
+ * @param username - name of the user
+ * @param roleGroup - group containing the user's roles
+ * @param dsJndiName - JNDI name of the datasource
+ * @param rolesQuery - prepared statement to query
+ * @param log - logger
+ * @param suspendResume - flag to indicate if transactions should be suspended/resumed
+ * @param tm - transaction manager
+ */
+ static void addRolesToGroup(String username, RoleGroup roleGroup, String dsJndiName, String rolesQuery, Logger log, boolean suspendResume, TransactionManager tm)
+ {
+ boolean trace = log.isTraceEnabled();
+ Connection conn = null;
+ PreparedStatement ps = null;
+ ResultSet rs = null;
+
+ if (suspendResume)
+ {
+ if (tm == null)
+ throw new IllegalStateException("Transaction Manager is null");
+ }
+ Transaction tx = null;
+ if (suspendResume)
+ {
+ try
+ {
+ tx = tm.suspend();
+ }
+ catch (SystemException e)
+ {
+ throw new RuntimeException(e);
+ }
+ if (trace)
+ log.trace("suspendAnyTransaction");
+ }
+
+ try
+ {
+ InitialContext ctx = new InitialContext();
+ DataSource ds = (DataSource) ctx.lookup(dsJndiName);
+ conn = ds.getConnection();
+ // Get the user role names
+ if (trace)
+ log.trace("Excuting query: " + rolesQuery + ", with username: " + username);
+ ps = conn.prepareStatement(rolesQuery);
+ try
+ {
+ ps.setString(1, username);
+ }
+ catch (ArrayIndexOutOfBoundsException ignore)
+ {
+ // The query may not have any parameters so just try it
+ }
+ rs = ps.executeQuery();
+ if (!rs.next())
+ {
+ if (trace)
+ log.trace("No roles found");
+ }
+
+ do
+ {
+ String name = rs.getString(1);
+ roleGroup.addRole(new SimpleRole(name));
+ }
+ while (rs.next());
+ }
+ catch (NamingException ex)
+ {
+ throw new IllegalArgumentException("Error looking up DataSource from: " + dsJndiName, ex);
+ }
+ catch (SQLException ex)
+ {
+ throw new IllegalArgumentException("Query failed", ex);
+ }
+ finally
+ {
+ if (rs != null)
+ {
+ try
+ {
+ rs.close();
+ }
+ catch (SQLException e)
+ {
+ }
+ }
+ if (ps != null)
+ {
+ try
+ {
+ ps.close();
+ }
+ catch (SQLException e)
+ {
+ }
+ }
+ if (conn != null)
+ {
+ try
+ {
+ conn.close();
+ }
+ catch (Exception ex)
+ {
+ }
+ }
+ if (suspendResume)
+ {
+ try
+ {
+ tm.resume(tx);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ if (trace)
+ log.trace("resumeAnyTransaction");
+ }
+ }
+ }
+
+}
Modified: trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/plugins/TransactionManagerLocator.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/plugins/TransactionManagerLocator.java 2011-05-26 18:23:11 UTC (rev 225)
+++ trunk/security-jboss-sx/jbosssx/src/main/java/org/jboss/security/plugins/TransactionManagerLocator.java 2011-06-15 15:31:14 UTC (rev 226)
@@ -40,6 +40,7 @@
{
private static Logger log = Logger.getLogger(TransactionManagerLocator.class);
private boolean trace = log.isTraceEnabled();
+ private static TransactionManager transactionManager;
public TransactionManagerLocator()
{
@@ -72,6 +73,8 @@
{
if(trace)
log.trace("Exception in getJBossTM:", ignore);
+ if (transactionManager != null)
+ tm = transactionManager;
}
}
return tm;
@@ -84,4 +87,9 @@
Method m = clz.getMethod("locate", new Class[]{});
return (TransactionManager) m.invoke(null, new Object[0]);
}
+
+ public static void setTransactionManager(TransactionManager transactionManager)
+ {
+ TransactionManagerLocator.transactionManager = transactionManager;
+ }
}
\ No newline at end of file
Modified: trunk/security-jboss-sx/jbosssx/src/test/java/org/jboss/test/authentication/JBossSecuritySubjectFactoryUnitTestCase.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/test/java/org/jboss/test/authentication/JBossSecuritySubjectFactoryUnitTestCase.java 2011-05-26 18:23:11 UTC (rev 225)
+++ trunk/security-jboss-sx/jbosssx/src/test/java/org/jboss/test/authentication/JBossSecuritySubjectFactoryUnitTestCase.java 2011-06-15 15:31:14 UTC (rev 226)
@@ -22,7 +22,10 @@
package org.jboss.test.authentication;
import java.lang.reflect.Method;
+import java.security.Principal;
import java.security.acl.Group;
+import java.util.Collections;
+import java.util.Enumeration;
import java.util.HashMap;
import java.util.Set;
@@ -162,11 +165,30 @@
JBossSecuritySubjectFactory subjectFactory = new JBossSecuritySubjectFactory();
Subject subject = subjectFactory.createSubject();
Set<Group> groups = subject.getPrincipals(Group.class);
- assertTrue("Principals contains scott", subject.getPrincipals().contains(new SimplePrincipal("scott")));
- assertTrue("Principals contains Roles", groups.contains(new SimplePrincipal("Roles")));
- Group roles = groups.iterator().next();
- assertTrue("TestRole is a role", roles.isMember(new SimplePrincipal("TestRole")));
- assertTrue("Role2 is a role", roles.isMember(new SimplePrincipal("Role2")));
+ Principal scott = new SimplePrincipal("scott");
+ assertTrue("Principals contains scott", subject.getPrincipals().contains(scott));
+ assertTrue("Principals contains Roles", groups.contains(new SimpleGroup("Roles")));
+ assertTrue("Principals contains CallerPrincipal", groups.contains(new SimpleGroup("CallerPrincipal")));
+ for (Group group : groups)
+ {
+ if (group.getName().equals("Roles"))
+ {
+ Enumeration<? extends Principal> roles = group.members();
+ assertEquals("Roles group has 2 entries", 2, Collections.list(roles).size());
+ assertTrue("TestRole is a role", group.isMember(new SimplePrincipal("TestRole")));
+ assertTrue("Role2 is a role", group.isMember(new SimplePrincipal("Role2")));
+ }
+ else if (group.getName().equals("CallerPrincipal"))
+ {
+ Enumeration<? extends Principal> roles = group.members();
+ assertEquals("CallerPrincipal group has 1 entry", 1, Collections.list(roles).size());
+ assertTrue("scott is the caller principal", group.isMember(scott));
+ }
+ else
+ {
+ fail("Another group was set: " + group.getName());
+ }
+ }
}
public void testSubjectCreationWithDefaultSecurityManagementImplementation() throws Exception
@@ -180,10 +202,29 @@
JBossSecuritySubjectFactory subjectFactory = new JBossSecuritySubjectFactory();
Subject subject = subjectFactory.createSubject("securityDomain");
Set<Group> groups = subject.getPrincipals(Group.class);
- assertTrue("Principals contains scott", subject.getPrincipals().contains(new SimplePrincipal("scott")));
- assertTrue("Principals contains Roles", groups.contains(new SimplePrincipal("Roles")));
- Group roles = groups.iterator().next();
- assertTrue("Role1 is a role", roles.isMember(new SimplePrincipal("Role1")));
+ Principal scott = new SimplePrincipal("scott");
+ assertTrue("Principals contains scott", subject.getPrincipals().contains(scott));
+ assertTrue("Principals contains Roles", groups.contains(new SimpleGroup("Roles")));
+ assertTrue("Principals contains CallerPrincipal", groups.contains(new SimpleGroup("CallerPrincipal")));
+ for (Group group : groups)
+ {
+ if (group.getName().equals("Roles"))
+ {
+ Enumeration<? extends Principal> roles = group.members();
+ assertEquals("Roles group has 1 entry", 1, Collections.list(roles).size());
+ assertTrue("Role1 is a role", group.isMember(new SimplePrincipal("Role1")));
+ }
+ else if (group.getName().equals("CallerPrincipal"))
+ {
+ Enumeration<? extends Principal> roles = group.members();
+ assertEquals("CallerPrincipal group has 1 entry", 1, Collections.list(roles).size());
+ assertTrue("scott is the caller principal", group.isMember(scott));
+ }
+ else
+ {
+ fail("Another group was set: " + group.getName());
+ }
+ }
}
}
Modified: trunk/security-jboss-sx/jbosssx/src/test/java/org/jboss/test/authentication/jaas/LoginModulesUnitTestCase.java
===================================================================
--- trunk/security-jboss-sx/jbosssx/src/test/java/org/jboss/test/authentication/jaas/LoginModulesUnitTestCase.java 2011-05-26 18:23:11 UTC (rev 225)
+++ trunk/security-jboss-sx/jbosssx/src/test/java/org/jboss/test/authentication/jaas/LoginModulesUnitTestCase.java 2011-06-15 15:31:14 UTC (rev 226)
@@ -25,6 +25,8 @@
import java.security.MessageDigest;
import java.security.Principal;
import java.security.acl.Group;
+import java.util.Collections;
+import java.util.Enumeration;
import java.util.HashMap;
import java.util.Set;
@@ -361,12 +363,31 @@
LoginContext lc = new LoginContext("testUsernamePassword", handler);
lc.login();
Subject subject = lc.getSubject();
- Set groups = subject.getPrincipals(Group.class);
- assertTrue("Principals contains scott", subject.getPrincipals().contains(new SimplePrincipal("scott")));
- assertTrue("Principals contains Roles", groups.contains(new SimplePrincipal("Roles")));
- Group roles = (Group) groups.iterator().next();
- assertTrue("TestRole is a role", roles.isMember(new SimplePrincipal("TestRole")));
- assertTrue("Role2 is a role", roles.isMember(new SimplePrincipal("Role2")));
+ Set<Group> groups = subject.getPrincipals(Group.class);
+ Principal scott = new SimplePrincipal("scott");
+ assertTrue("Principals contains scott", subject.getPrincipals().contains(scott));
+ assertTrue("Principals contains Roles", groups.contains(new SimpleGroup("Roles")));
+ assertTrue("Principals contains CallerPrincipal", groups.contains(new SimpleGroup("CallerPrincipal")));
+ for (Group group : groups)
+ {
+ if (group.getName().equals("Roles"))
+ {
+ Enumeration<? extends Principal> roles = group.members();
+ assertEquals("Roles group has 2 entries", 2, Collections.list(roles).size());
+ assertTrue("TestRole is a role", group.isMember(new SimplePrincipal("TestRole")));
+ assertTrue("Role2 is a role", group.isMember(new SimplePrincipal("Role2")));
+ }
+ else if (group.getName().equals("CallerPrincipal"))
+ {
+ Enumeration<? extends Principal> roles = group.members();
+ assertEquals("CallerPrincipal group has 1 entry", 1, Collections.list(roles).size());
+ assertTrue("scott is the caller principal", group.isMember(scott));
+ }
+ else
+ {
+ fail("Another group was set: " + group.getName());
+ }
+ }
lc.logout();
}
@@ -377,12 +398,31 @@
LoginContext lc = new LoginContext("testUsernamePasswordHash", handler);
lc.login();
Subject subject = lc.getSubject();
- Set groups = subject.getPrincipals(Group.class);
- assertTrue("Principals contains scott", subject.getPrincipals().contains(new SimplePrincipal("scott")));
- assertTrue("Principals contains Roles", groups.contains(new SimplePrincipal("Roles")));
- Group roles = (Group) groups.iterator().next();
- assertTrue("TestRole is a role", roles.isMember(new SimplePrincipal("TestRole")));
- assertTrue("Role2 is a role", roles.isMember(new SimplePrincipal("Role2")));
+ Set<Group> groups = subject.getPrincipals(Group.class);
+ Principal scott = new SimplePrincipal("scott");
+ assertTrue("Principals contains scott", subject.getPrincipals().contains(scott));
+ assertTrue("Principals contains Roles", groups.contains(new SimpleGroup("Roles")));
+ assertTrue("Principals contains CallerPrincipal", groups.contains(new SimpleGroup("CallerPrincipal")));
+ for (Group group : groups)
+ {
+ if (group.getName().equals("Roles"))
+ {
+ Enumeration<? extends Principal> roles = group.members();
+ assertEquals("Roles group has 2 entries", 2, Collections.list(roles).size());
+ assertTrue("TestRole is a role", group.isMember(new SimplePrincipal("TestRole")));
+ assertTrue("Role2 is a role", group.isMember(new SimplePrincipal("Role2")));
+ }
+ else if (group.getName().equals("CallerPrincipal"))
+ {
+ Enumeration<? extends Principal> roles = group.members();
+ assertEquals("CallerPrincipal group has 1 entry", 1, Collections.list(roles).size());
+ assertTrue("scott is the caller principal", group.isMember(scott));
+ }
+ else
+ {
+ fail("Another group was set: " + group.getName());
+ }
+ }
lc.logout();
}
@@ -394,11 +434,28 @@
LoginContext lc = new LoginContext("testAnon", handler);
lc.login();
Subject subject = lc.getSubject();
- Set groups = subject.getPrincipals(Group.class);
- assertTrue("Principals contains nobody", subject.getPrincipals().contains(new SimplePrincipal("nobody")));
- assertTrue("Principals contains Roles", groups.contains(new SimplePrincipal("Roles")));
- Group roles = (Group) groups.iterator().next();
- assertTrue("Roles has no members", roles.members().hasMoreElements() == false);
+ Set<Group> groups = subject.getPrincipals(Group.class);
+ Principal nobody = new SimplePrincipal("nobody");
+ assertTrue("Principals contains nobody", subject.getPrincipals().contains(nobody));
+ assertTrue("Principals contains Roles", groups.contains(new SimpleGroup("Roles")));
+ assertTrue("Principals contains CallerPrincipal", groups.contains(new SimpleGroup("CallerPrincipal")));
+ for (Group group : groups)
+ {
+ if (group.getName().equals("Roles"))
+ {
+ assertTrue("Roles has no members", !group.members().hasMoreElements());
+ }
+ else if (group.getName().equals("CallerPrincipal"))
+ {
+ Enumeration<? extends Principal> roles = group.members();
+ assertEquals("CallerPrincipal group has 1 entry", 1, Collections.list(roles).size());
+ assertTrue("scott is the caller principal", group.isMember(nobody));
+ }
+ else
+ {
+ fail("Another group was set: " + group.getName());
+ }
+ }
lc.logout();
}
@@ -424,13 +481,32 @@
LoginContext lc = new LoginContext("testIdentity");
lc.login();
Subject subject = lc.getSubject();
- Set groups = subject.getPrincipals(Group.class);
- assertTrue("Principals contains stark", subject.getPrincipals().contains(new SimplePrincipal("stark")));
- assertTrue("Principals contains Roles", groups.contains(new SimplePrincipal("Roles")));
- Group roles = (Group) groups.iterator().next();
- assertTrue("Role2 is not a role", roles.isMember(new SimplePrincipal("Role2")) == false);
- assertTrue("Role3 is a role", roles.isMember(new SimplePrincipal("Role3")));
- assertTrue("Role4 is a role", roles.isMember(new SimplePrincipal("Role4")));
+ Set<Group> groups = subject.getPrincipals(Group.class);
+ Principal stark = new SimplePrincipal("stark");
+ assertTrue("Principals contains stark", subject.getPrincipals().contains(stark));
+ assertTrue("Principals contains Roles", groups.contains(new SimpleGroup("Roles")));
+ assertTrue("Principals contains CallerPrincipal", groups.contains(new SimpleGroup("CallerPrincipal")));
+ for (Group group : groups)
+ {
+ if (group.getName().equals("Roles"))
+ {
+ Enumeration<? extends Principal> roles = group.members();
+ assertEquals("Roles group has 2 entries", 2, Collections.list(roles).size());
+ assertTrue("Role2 is not a role", !group.isMember(new SimplePrincipal("Role2")));
+ assertTrue("Role3 is a role", group.isMember(new SimplePrincipal("Role3")));
+ assertTrue("Role4 is a role", group.isMember(new SimplePrincipal("Role4")));
+ }
+ else if (group.getName().equals("CallerPrincipal"))
+ {
+ Enumeration<? extends Principal> roles = group.members();
+ assertEquals("CallerPrincipal group has 1 entry", 1, Collections.list(roles).size());
+ assertTrue("scott is the caller principal", group.isMember(stark));
+ }
+ else
+ {
+ fail("Another group was set: " + group.getName());
+ }
+ }
lc.logout();
}
@@ -441,12 +517,31 @@
LoginContext lc = new LoginContext("testSimple", handler);
lc.login();
Subject subject = lc.getSubject();
- Set groups = subject.getPrincipals(Group.class);
- assertTrue("Principals contains jduke", subject.getPrincipals().contains(new SimplePrincipal("jduke")));
- assertTrue("Principals contains Roles", groups.contains(new SimplePrincipal("Roles")));
- Group roles = (Group) groups.iterator().next();
- assertTrue("user is a role", roles.isMember(new SimplePrincipal("user")));
- assertTrue("guest is a role", roles.isMember(new SimplePrincipal("guest")));
+ Set<Group> groups = subject.getPrincipals(Group.class);
+ Principal jduke = new SimplePrincipal("jduke");
+ assertTrue("Principals contains jduke", subject.getPrincipals().contains(jduke));
+ assertTrue("Principals contains Roles", groups.contains(new SimpleGroup("Roles")));
+ assertTrue("Principals contains CallerPrincipal", groups.contains(new SimpleGroup("CallerPrincipal")));
+ for (Group group : groups)
+ {
+ if (group.getName().equals("Roles"))
+ {
+ Enumeration<? extends Principal> roles = group.members();
+ assertEquals("Roles group has 2 entries", 2, Collections.list(roles).size());
+ assertTrue("user is a role", group.isMember(new SimplePrincipal("user")));
+ assertTrue("guest is a role", group.isMember(new SimplePrincipal("guest")));
+ }
+ else if (group.getName().equals("CallerPrincipal"))
+ {
+ Enumeration<? extends Principal> roles = group.members();
+ assertEquals("CallerPrincipal group has 1 entry", 1, Collections.list(roles).size());
+ assertTrue("scott is the caller principal", group.isMember(jduke));
+ }
+ else
+ {
+ fail("Another group was set: " + group.getName());
+ }
+ }
lc.logout();
}
More information about the jboss-cvs-commits
mailing list