/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, 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.test.security.test;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.net.URL;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.Principal;
import java.security.acl.Group;
import java.security.cert.X509Certificate;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import javax.naming.InitialContext;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManagerFactory;
import javax.resource.spi.security.PasswordCredential;
import javax.security.auth.Subject;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.Configuration;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import javax.sql.DataSource;
import junit.framework.TestSuite;
import org.jboss.crypto.CryptoUtil;
import org.jboss.logging.Logger;
import org.jboss.security.AuthenticationManager;
import org.jboss.security.SecurityAssociation;
import org.jboss.security.SecurityDomain;
import org.jboss.security.SimpleGroup;
import org.jboss.security.SimplePrincipal;
import org.jboss.security.auth.callback.SecurityAssociationHandler;
import org.jboss.security.auth.callback.UsernamePasswordHandler;
import org.jboss.security.auth.spi.UsernamePasswordLoginModule;
import org.jboss.security.plugins.JaasSecurityDomain;
import org.jboss.test.JBossTestCase;
/** Tests of the LoginModule classes.
@author Scott.Stark@jboss.org
@version $Revision: 81036 $
*/
public class LoginModulesUnitTestCase extends JBossTestCase
{
private static Logger log = Logger.getLogger(LoginModulesUnitTestCase.class);
/** Hard coded login configurations for the test cases. The configuration
name corresponds to the unit test function that uses the configuration.
*/
static class TestConfig extends Configuration
{
public void refresh()
{
}
public AppConfigurationEntry[] getAppConfigurationEntry(String name)
{
AppConfigurationEntry[] entry = null;
try
{
Class[] parameterTypes = {};
Method m = getClass().getDeclaredMethod(name, parameterTypes);
Object[] args = {};
entry = (AppConfigurationEntry[]) m.invoke(this, args);
}
catch(Exception e)
{
}
return entry;
}
AppConfigurationEntry[] testClientLogin()
{
String name = "org.jboss.security.ClientLoginModule";
HashMap options = new HashMap();
options.put("restore-login-identity", "true");
AppConfigurationEntry ace = new AppConfigurationEntry(name,
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
AppConfigurationEntry[] entry = {ace};
return entry;
}
AppConfigurationEntry[] testIdentity()
{
String name = "org.jboss.security.auth.spi.IdentityLoginModule";
HashMap options = new HashMap();
options.put("principal", "stark");
options.put("roles", "Role3,Role4");
AppConfigurationEntry ace = new AppConfigurationEntry(name,
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
AppConfigurationEntry[] entry = {ace};
return entry;
}
AppConfigurationEntry[] testJdbc()
{
String name = "org.jboss.security.auth.spi.DatabaseServerLoginModule";
HashMap options = new HashMap();
options.put("dsJndiName", "testJdbc");
options.put("principalsQuery", "select Password from Principals where PrincipalID=?");
options.put("rolesQuery", "select Role, RoleGroup from Roles where PrincipalID=?");
options.put("suspendResume", "false");
AppConfigurationEntry ace = new AppConfigurationEntry(name,
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
AppConfigurationEntry[] entry = {ace};
return entry;
}
AppConfigurationEntry[] testSimple()
{
String name = "org.jboss.security.auth.spi.SimpleServerLoginModule";
AppConfigurationEntry ace = new AppConfigurationEntry(name,
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, new HashMap());
AppConfigurationEntry[] entry = {ace};
return entry;
}
AppConfigurationEntry[] testUsernamePassword()
{
return other();
}
AppConfigurationEntry[] testUsernamePasswordHash()
{
HashMap options = new HashMap();
options.put("hashAlgorithm", "MD5");
options.put("hashEncoding", "base64");
AppConfigurationEntry ace = new AppConfigurationEntry(HashTestLoginModule.class.getName(),
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
AppConfigurationEntry[] entry = {ace};
return entry;
}
AppConfigurationEntry[] testUsernamePasswordHashWithDigestCallback()
{
HashMap options = new HashMap();
options.put("hashAlgorithm", "MD5");
options.put("hashEncoding", "base64");
options.put("hashCharset", "UTF-8");
options.put("digestCallback", "org.jboss.test.security.test.TestDigestCallback");
options.put("digest.preSalt", "pre");
options.put("digest.postSalt", "post");
AppConfigurationEntry ace = new AppConfigurationEntry(HashTestDigestCallbackLoginModule.class.getName(),
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
AppConfigurationEntry[] entry = {ace};
return entry;
}
AppConfigurationEntry[] testAnon()
{
String name = "org.jboss.security.auth.spi.AnonLoginModule";
HashMap options = new HashMap();
options.put("unauthenticatedIdentity", "nobody");
AppConfigurationEntry ace = new AppConfigurationEntry(name,
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
AppConfigurationEntry[] entry = {ace};
return entry;
}
AppConfigurationEntry[] testNull()
{
String name = "org.jboss.security.auth.spi.AnonLoginModule";
HashMap options = new HashMap();
AppConfigurationEntry ace = new AppConfigurationEntry(name,
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
AppConfigurationEntry[] entry = {ace};
return entry;
}
AppConfigurationEntry[] testUsersRoles()
{
String name = "org.jboss.security.auth.spi.UsersRolesLoginModule";
HashMap options = new HashMap();
options.put("usersProperties", "security/users.properties");
options.put("rolesProperties", "security/roles.properties");
AppConfigurationEntry ace = new AppConfigurationEntry(name,
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
AppConfigurationEntry[] entry = {ace};
return entry;
}
AppConfigurationEntry[] testUsersRolesHash()
{
String name = "org.jboss.security.auth.spi.UsersRolesLoginModule";
HashMap options = new HashMap();
options.put("usersProperties", "security/usersb64.properties");
options.put("hashAlgorithm", "MD5");
options.put("hashEncoding", "base64");
AppConfigurationEntry ace = new AppConfigurationEntry(name,
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
AppConfigurationEntry[] entry = {ace};
return entry;
}
AppConfigurationEntry[] testAnonUsersRoles()
{
String name = "org.jboss.security.auth.spi.UsersRolesLoginModule";
HashMap options = new HashMap();
options.put("usersProperties", "security/users.properties");
options.put("rolesProperties", "security/roles.properties");
options.put("unauthenticatedIdentity", "nobody");
AppConfigurationEntry ace = new AppConfigurationEntry(name,
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
AppConfigurationEntry[] entry = {ace};
return entry;
}
AppConfigurationEntry[] testControlFlags()
{
String name1 = "org.jboss.security.auth.spi.UsersRolesLoginModule";
HashMap options1 = new HashMap();
options1.put("usersProperties", "security/users.properties");
options1.put("rolesProperties", "security/roles.properties");
AppConfigurationEntry ace1 = new AppConfigurationEntry(name1,
AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT, options1);
String name2 = "org.jboss.security.auth.spi.DatabaseServerLoginModule";
HashMap options = new HashMap();
options.put("dsJndiName", "testJdbc");
options.put("principalsQuery", "select Password from Principals where PrincipalID=?");
options.put("rolesQuery", "select Role, RoleGroup from Roles where PrincipalID=?");
options.put("suspendResume", "false");
AppConfigurationEntry ace2 = new AppConfigurationEntry(name2,
AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT, options);
AppConfigurationEntry[] entry = {ace1, ace2};
return entry;
}
AppConfigurationEntry[] testJCACallerIdentity()
{
String name = "org.jboss.resource.security.CallerIdentityLoginModule";
HashMap options = new HashMap();
options.put("userName", "jduke");
options.put("password", "theduke");
options.put("managedConnectionFactoryName", "jboss:name=fakeMCF");
options.put("ignoreMissigingMCF", Boolean.TRUE);
AppConfigurationEntry ace = new AppConfigurationEntry(name,
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
AppConfigurationEntry[] entry = {ace};
return entry;
}
AppConfigurationEntry[] testJaasSecurityDomainIdentityLoginModule()
{
String name = "org.jboss.resource.security.JaasSecurityDomainIdentityLoginModule";
HashMap options = new HashMap();
options.put("userName", "sa");
options.put("password", "E5gtGMKcXPP");
options.put("managedConnectionFactoryName", "jboss.jca:service=LocalTxCM,name=DefaultDS");
options.put("ignoreMissigingMCF", Boolean.TRUE);
options.put("jaasSecurityDomain", "jboss.test:service=JaasSecurityDomain,domain=testJaasSecurityDomainIdentityLoginModule");
AppConfigurationEntry ace = new AppConfigurationEntry(name,
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
AppConfigurationEntry[] entry = {ace};
return entry;
}
AppConfigurationEntry[] testCertLogin()
{
String name = "org.jboss.security.auth.spi.BaseCertLoginModule";
HashMap options = new HashMap();
options.put("securityDomain", "testCertLogin");
AppConfigurationEntry ace = new AppConfigurationEntry(name,
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
AppConfigurationEntry[] entry = {ace};
return entry;
}
AppConfigurationEntry[] testCertRoles()
{
String name = "org.jboss.security.auth.spi.CertRolesLoginModule";
HashMap options = new HashMap();
options.put("securityDomain", "testCertRoles");
options.put("usersProperties", "security/users.properties");
options.put("rolesProperties", "security/roles.properties");
AppConfigurationEntry ace = new AppConfigurationEntry(name,
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
AppConfigurationEntry[] entry = {ace};
return entry;
}
AppConfigurationEntry[] other()
{
AppConfigurationEntry ace = new AppConfigurationEntry(TestLoginModule.class.getName(),
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, new HashMap());
AppConfigurationEntry[] entry = {ace};
return entry;
}
}
public static class TestLoginModule extends UsernamePasswordLoginModule
{
protected Group[] getRoleSets()
{
SimpleGroup roles = new SimpleGroup("Roles");
Group[] roleSets = {roles};
roles.addMember(new SimplePrincipal("TestRole"));
roles.addMember(new SimplePrincipal("Role2"));
return roleSets;
}
/** This represents the 'true' password
*/
protected String getUsersPassword()
{
return "secret";
}
}
public static class HashTestLoginModule extends TestLoginModule
{
/** This represents the 'true' password in its hashed form
*/
protected String getUsersPassword()
{
MessageDigest md = null;
try
{
md = MessageDigest.getInstance("MD5");
}
catch(Exception e)
{
e.printStackTrace();
}
byte[] passwordBytes = "secret".getBytes();
byte[] hash = md.digest(passwordBytes);
String passwordHash = CryptoUtil.encodeBase64(hash);
return passwordHash;
}
}
public static class HashTestDigestCallbackLoginModule extends TestLoginModule
{
/** This represents the 'true' password in its hashed form
*/
protected String getUsersPassword()
{
MessageDigest md = null;
try
{
md = MessageDigest.getInstance("MD5");
}
catch(Exception e)
{
e.printStackTrace();
}
byte[] passwordBytes = "secret".getBytes();
md.update("pre".getBytes());
md.update(passwordBytes);
md.update("post".getBytes());
byte[] hash = md.digest();
String passwordHash = CryptoUtil.encodeBase64(hash);
return passwordHash;
}
}
/** A pseudo DataSource that is used to provide Hypersonic db
connections to the DatabaseServerLoginModule.
*/
static class TestDS implements DataSource, Serializable
{
private static final long serialVersionUID = 1;
public java.sql.Connection getConnection() throws java.sql.SQLException
{
return getConnection("sa", "");
}
public java.sql.Connection getConnection(String user, String pass) throws java.sql.SQLException
{
java.sql.Connection con = null;
String jdbcURL = "";
try
{
jdbcURL = "jdbc:hsqldb:hsql://" + System.getProperty("jbosstest.server.host", "localhost") + ":1701";
con = DriverManager.getConnection(jdbcURL, user, pass);
}
catch(java.sql.SQLException sqle)
{
jdbcURL = "jdbc:hsqldb:."; // only memory jdbc url
con = DriverManager.getConnection(jdbcURL, user, pass);
}
return con;
}
public java.io.PrintWriter getLogWriter() throws java.sql.SQLException
{
return null;
}
public void setLogWriter(java.io.PrintWriter out)
throws java.sql.SQLException
{
}
public int getLoginTimeout() throws java.sql.SQLException
{
return 0;
}
public void setLoginTimeout(int seconds) throws java.sql.SQLException
{
}
public boolean isWrapperFor(Class<?> iface) throws SQLException
{
return false;
}
public <T> T unwrap(Class<T> iface) throws SQLException
{
throw new SQLException("No wrapper");
}
}
static class TestSecurityDomain implements SecurityDomain, Serializable
{
private static final long serialVersionUID = 1;
private transient KeyStore store;
public KeyStore getKeyStore() throws SecurityException
{
return store;
}
public KeyManagerFactory getKeyManagerFactory() throws SecurityException
{
return null;
}
public KeyStore getTrustStore() throws SecurityException
{
return store;
}
public TrustManagerFactory getTrustManagerFactory() throws SecurityException
{
return null;
}
public String getSecurityDomain()
{
return null;
}
public Subject getActiveSubject()
{
return null;
}
public boolean isValid(Principal principal, Object credential,
Subject activeSubject)
{
return false;
}
public boolean isValid(Principal principal, Object credential)
{
return false;
}
public Principal getPrincipal(Principal principal)
{
return null;
}
public boolean doesUserHaveRole(Principal principal, Set roles)
{
return false;
}
public Set getUserRoles(Principal principal)
{
return null;
}
private void readObject(java.io.ObjectInputStream in)
throws IOException
{
try
{
store = KeyStore.getInstance("JKS");
ClassLoader loader = Thread.currentThread().getContextClassLoader();
URL resURL = loader.getResource("security/tst.keystore");
store.load(resURL.openStream(), "unit-tests".toCharArray());
}
catch(Exception e)
{
throw new IOException(e.toString());
}
}
/**
* @see AuthenticationManager#getTargetPrincipal(Principal,Map)
*/
public Principal getTargetPrincipal(Principal anotherDomainPrincipal, Map contextMap)
{
throw new RuntimeException("Not implemented yet");
}
}
public LoginModulesUnitTestCase(String testName)
{
super(testName);
}
protected void setUp() throws Exception
{
// Install the custom JAAS configuration
Configuration.setConfiguration(new TestConfig());
super.setUp();
log = getLog();
}
public void testClientLogin() throws Exception
{
log.info("testClientLogin");
UsernamePasswordHandler handler = new UsernamePasswordHandler("scott", "secret".toCharArray());
LoginContext lc = new LoginContext("testClientLogin", handler);
lc.login();
Subject subject = lc.getSubject();
Principal scott = new SimplePrincipal("scott");
assertTrue("Principals contains scott", subject.getPrincipals().contains(scott));
Principal saPrincipal = SecurityAssociation.getPrincipal();
assertTrue("SecurityAssociation.getPrincipal == scott", saPrincipal.equals(scott));
UsernamePasswordHandler handler2 = new UsernamePasswordHandler("scott2", "secret2".toCharArray());
LoginContext lc2 = new LoginContext("testClientLogin", handler2);
lc2.login();
Principal scott2 = new SimplePrincipal("scott2");
saPrincipal = SecurityAssociation.getPrincipal();
assertTrue("SecurityAssociation.getPrincipal == scott2", saPrincipal.equals(scott2));
lc2.logout();
saPrincipal = SecurityAssociation.getPrincipal();
assertTrue("SecurityAssociation.getPrincipal == scott", saPrincipal.equals(scott));
lc.logout();
}
public void testUsernamePassword() throws Exception
{
log.info("testUsernamePassword");
UsernamePasswordHandler handler = new UsernamePasswordHandler("scott", "secret".toCharArray());
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")));
lc.logout();
}
public void testUsernamePasswordHash() throws Exception
{
log.info("testUsernamePasswordHash");
UsernamePasswordHandler handler = new UsernamePasswordHandler("scott", "secret".toCharArray());
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")));
lc.logout();
}
public void testUsernamePasswordHashWithDigestCallback() throws Exception
{
log.info("testUsernamePasswordHashWithDigestCallback");
// secret in ascii
byte[] passBytes = {115, 101, 99, 114, 101, 116};
String pass = new String(passBytes, "UTF-8");
UsernamePasswordHandler handler = new UsernamePasswordHandler("scott", pass.toCharArray());
LoginContext lc = new LoginContext("testUsernamePasswordHashWithDigestCallback", 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")));
lc.logout();
}
public void testUsersRoles() throws Exception
{
log.info("testUsersRoles");
UsernamePasswordHandler handler = new UsernamePasswordHandler("scott", "echoman".toCharArray());
LoginContext lc = new LoginContext("testUsersRoles", 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")));
assertTrue("Principals contains CallerPrincipal", groups.contains(new SimplePrincipal("CallerPrincipal")));
Group roles = (Group) groups.iterator().next();
Iterator groupsIter = groups.iterator();
while( groupsIter.hasNext() )
{
roles = (Group) groupsIter.next();
if( roles.getName().equals("Roles") )
{
assertTrue("Echo is a role", roles.isMember(new SimplePrincipal("Echo")));
assertTrue("Java is NOT a role", roles.isMember(new SimplePrincipal("Java")) == false);
assertTrue("Coder is NOT a role", roles.isMember(new SimplePrincipal("Coder")) == false);
}
else if( roles.getName().equals("CallerPrincipal") )
{
log.info("CallerPrincipal is "+roles.members().nextElement());
boolean isMember = roles.isMember(new SimplePrincipal("callerScott"));
assertTrue("CallerPrincipal is callerScott", isMember);
}
}
lc.logout();
handler = new UsernamePasswordHandler("stark", "javaman".toCharArray());
lc = new LoginContext("testUsersRoles", handler);
lc.login();
subject = lc.getSubject();
groups = subject.getPrincipals(Group.class);
assertTrue("Principals contains stark", subject.getPrincipals().contains(new SimplePrincipal("stark")));
assertTrue("Principals contains Roles", groups.contains(new SimplePrincipal("Roles")));
assertTrue("Principals contains CallerPrincipal", groups.contains(new SimplePrincipal("CallerPrincipal")));
groupsIter = groups.iterator();
while( groupsIter.hasNext() )
{
roles = (Group) groupsIter.next();
if( roles.getName().equals("Roles") )
{
assertTrue("Echo is NOT a role", roles.isMember(new SimplePrincipal("Echo")) == false);
assertTrue("Java is a role", roles.isMember(new SimplePrincipal("Java")));
assertTrue("Coder is a role", roles.isMember(new SimplePrincipal("Coder")));
}
else if( roles.getName().equals("CallerPrincipal") )
{
log.info("CallerPrincipal is "+roles.members().nextElement());
boolean isMember = roles.isMember(new SimplePrincipal("callerStark"));
assertTrue("CallerPrincipal is callerStark", isMember);
}
}
lc.logout();
// Test the usernames with common prefix
log.info("Testing similar usernames");
handler = new UsernamePasswordHandler("jdukeman", "anotherduke".toCharArray());
lc = new LoginContext("testUsersRoles", handler);
lc.login();
subject = lc.getSubject();
groups = subject.getPrincipals(Group.class);
assertTrue("Principals contains jdukeman", subject.getPrincipals().contains(new SimplePrincipal("jdukeman")));
assertTrue("Principals contains Roles", groups.contains(new SimplePrincipal("Roles")));
assertTrue("Principals contains CallerPrincipal", groups.contains(new SimplePrincipal("CallerPrincipal")));
groupsIter = groups.iterator();
while( groupsIter.hasNext() )
{
roles = (Group) groupsIter.next();
if( roles.getName().equals("Roles") )
{
assertTrue("Role1 is NOT a role", roles.isMember(new SimplePrincipal("Role1")) == false);
assertTrue("Role2 is a role", roles.isMember(new SimplePrincipal("Role2")));
assertTrue("Role3 is a role", roles.isMember(new SimplePrincipal("Role3")));
}
else if( roles.getName().equals("CallerPrincipal") )
{
log.info("CallerPrincipal is "+roles.members().nextElement());
boolean isMember = roles.isMember(new SimplePrincipal("callerJdukeman"));
assertTrue("CallerPrincipal is callerJdukeman", isMember);
}
}
lc.logout();
}
public void testUsersRolesHash() throws Exception
{
log.info("testUsersRolesHash");
UsernamePasswordHandler handler = new UsernamePasswordHandler("scott", "echoman".toCharArray());
LoginContext lc = new LoginContext("testUsersRolesHash", 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")));
assertTrue("Principals contains CallerPrincipal", groups.contains(new SimplePrincipal("CallerPrincipal")));
Group roles = (Group) groups.iterator().next();
Iterator groupsIter = groups.iterator();
while( groupsIter.hasNext() )
{
roles = (Group) groupsIter.next();
if( roles.getName().equals("Roles") )
{
assertTrue("Echo is a role", roles.isMember(new SimplePrincipal("Echo")));
assertTrue("Java is NOT a role", roles.isMember(new SimplePrincipal("Java")) == false);
assertTrue("Coder is NOT a role", roles.isMember(new SimplePrincipal("Coder")) == false);
}
else if( roles.getName().equals("CallerPrincipal") )
{
log.info("CallerPrincipal is "+roles.members().nextElement());
boolean isMember = roles.isMember(new SimplePrincipal("callerScott"));
assertTrue("CallerPrincipal is callerScott", isMember);
}
}
lc.logout();
}
public void testAnonUsersRoles() throws Exception
{
log.info("testAnonUsersRoles");
UsernamePasswordHandler handler = new UsernamePasswordHandler(null, null);
LoginContext lc = new LoginContext("testAnonUsersRoles", 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);
lc.logout();
}
public void testAnon() throws Exception
{
log.info("testAnon");
UsernamePasswordHandler handler = new UsernamePasswordHandler(null, null);
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);
lc.logout();
}
public void testNull() throws Exception
{
log.info("testNull");
UsernamePasswordHandler handler = new UsernamePasswordHandler(null, null);
LoginContext lc = new LoginContext("testNull", handler);
try
{
lc.login();
fail("Should not be able to login as null, null");
}
catch(LoginException e)
{
// Ok
}
}
public void testIdentity() throws Exception
{
log.info("testIdentity");
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")));
lc.logout();
}
public void testJCACallerIdentity() throws Exception
{
log.info("testJCACallerIdentity");
MBeanServer server = MBeanServerFactory.createMBeanServer("jboss");
LoginContext lc = new LoginContext("testJCACallerIdentity");
lc.login();
Subject subject = lc.getSubject();
assertTrue("Principals contains jduke", subject.getPrincipals().contains(new SimplePrincipal("jduke")));
Set creds = subject.getPrivateCredentials(PasswordCredential.class);
PasswordCredential pc = (PasswordCredential) creds.iterator().next();
String username = pc.getUserName();
String password = new String(pc.getPassword());
assertTrue("PasswordCredential.username = jduke", username.equals("jduke"));
assertTrue("PasswordCredential.password = theduke", password.equals("theduke"));
lc.logout();
// Test the override of the default identity
SecurityAssociation.setPrincipal(new SimplePrincipal("jduke2"));
SecurityAssociation.setCredential("theduke2".toCharArray());
lc.login();
subject = lc.getSubject();
Set principals = subject.getPrincipals();
assertTrue("Principals contains jduke2", principals.contains(new SimplePrincipal("jduke2")));
assertTrue("Principals does not contains jduke", principals.contains(new SimplePrincipal("jduke")) == false);
creds = subject.getPrivateCredentials(PasswordCredential.class);
pc = (PasswordCredential) creds.iterator().next();
username = pc.getUserName();
password = new String(pc.getPassword());
assertTrue("PasswordCredential.username = jduke2", username.equals("jduke2"));
assertTrue("PasswordCredential.password = theduke2", password.equals("theduke2"));
lc.logout();
MBeanServerFactory.releaseMBeanServer(server);
}
public void testJaasSecurityDomainIdentityLoginModule() throws Exception
{
log.info("testJaasSecurityDomainIdentityLoginModule");
MBeanServer server = MBeanServerFactory.createMBeanServer("jboss");
JaasSecurityDomain secDomain = new JaasSecurityDomain("testEncodeDecode");
secDomain.setSalt("abcdefgh");
secDomain.setIterationCount(13);
secDomain.setKeyStorePass("master");
secDomain.setManagerServiceName(null);
secDomain.start();
ObjectName name = new ObjectName("jboss.test:service=JaasSecurityDomain,domain=testJaasSecurityDomainIdentityLoginModule");
server.registerMBean(secDomain, name);
LoginContext lc = new LoginContext("testJaasSecurityDomainIdentityLoginModule");
lc.login();
Subject subject = lc.getSubject();
assertTrue("Principals contains sa", subject.getPrincipals().contains(new SimplePrincipal("sa")));
Set creds = subject.getPrivateCredentials(PasswordCredential.class);
PasswordCredential pc = (PasswordCredential) creds.iterator().next();
String username = pc.getUserName();
String password = new String(pc.getPassword());
assertTrue("PasswordCredential.username = sa", username.equals("sa"));
assertTrue("PasswordCredential.password = ", password.equals(""));
lc.logout();
server.unregisterMBean(name);
MBeanServerFactory.releaseMBeanServer(server);
}
public void testSimple() throws Exception
{
log.info("testSimple");
UsernamePasswordHandler handler = new UsernamePasswordHandler("jduke", "jduke".toCharArray());
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")));
lc.logout();
}
/** Use this DDL script to setup tables:
; First load the JDBC driver and open a database.
d org.enhydra.instantdb.jdbc.idbDriver;
o jdbc:idb=/usr/local/src/cvsroot/jBoss/jboss/dist/conf/default/instantdb.properties;
; Create the Principal table
e DROP TABLE Principals ;
e CREATE TABLE Principals (
PrincipalID VARCHAR(64) PRIMARY KEY,
Password VARCHAR(64) );
; put some initial data in the table
e INSERT INTO Principals VALUES ("scott", "echoman");
e INSERT INTO Principals VALUES ("stark", "javaman");
; Create the Roles table
e DROP TABLE Roles;
e CREATE TABLE Roles (
PrincipalID VARCHAR(64) PRIMARY KEY,
Role VARCHAR(64),
RoleGroup VARCHAR(64) );
; put some initial data in the table
e INSERT INTO Roles VALUES ("scott", "Echo", "");
e INSERT INTO Roles VALUES ("scott", "caller_scott", "CallerPrincipal");
e INSERT INTO Roles VALUES ("stark", "Java", "");
e INSERT INTO Roles VALUES ("stark", "Coder", "");
e INSERT INTO Roles VALUES ("stark", "caller_stark", "CallerPrincipal");
c close;
*/
public void testJdbc() throws Exception
{
log.info("testJdbc");
Connection conn = setupLoginTables();
try
{
UsernamePasswordHandler handler = new UsernamePasswordHandler("stark", "javaman".toCharArray());
LoginContext lc = new LoginContext("testJdbc", handler);
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 = findRolesGroup(groups);
assertTrue("Java is a role", roles.isMember(new SimplePrincipal("Java")));
assertTrue("Coder is a role", roles.isMember(new SimplePrincipal("Coder")));
lc.logout();
}
finally
{
conn.close();
}
}
public void testControlFlags() throws Exception
{
log.info("testControlFlags");
Connection conn = setupLoginTables();
try
{
Configuration cfg = Configuration.getConfiguration();
AppConfigurationEntry[] ace = cfg.getAppConfigurationEntry("testControlFlags");
for(int n = 0; n < ace.length; n ++)
{
assertTrue("testControlFlags flag==SUFFICIENT",
ace[n].getControlFlag() == AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT);
log.info(ace[n].getControlFlag());
}
/* Test that the UsersRolesLoginModule is sufficient to login. Only the
users.properties file has a jduke=theduke username to password mapping,
and the DatabaseServerLoginModule will fail.
*/
UsernamePasswordHandler handler = new UsernamePasswordHandler("jduke", "theduke".toCharArray());
LoginContext lc = new LoginContext("testControlFlags", 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 = findRolesGroup(groups);
// Only the roles from the DatabaseServerLoginModule should exist
assertTrue("Role1 is a role", roles.isMember(new SimplePrincipal("Role1")));
assertTrue("Role2 is a role", roles.isMember(new SimplePrincipal("Role2")));
assertTrue("Role3 is NOT a role", !roles.isMember(new SimplePrincipal("Role3")));
assertTrue("Role4 is NOT a role", !roles.isMember(new SimplePrincipal("Role4")));
lc.logout();
/* Test that the DatabaseServerLoginModule is sufficient to login. Only the
Principals table has a jduke=jduke username to password mapping, and
the UsersRolesLoginModule will fail.
*/
handler = new UsernamePasswordHandler("jduke", "jduke".toCharArray());
lc = new LoginContext("testControlFlags", handler);
lc.login();
subject = lc.getSubject();
groups = subject.getPrincipals(Group.class);
assertTrue("Principals contains jduke", subject.getPrincipals().contains(new SimplePrincipal("jduke")));
assertTrue("Principals contains Roles", groups.contains(new SimplePrincipal("Roles")));
roles = (Group) groups.iterator().next();
Enumeration iter = roles.members();
while( iter.hasMoreElements() )
log.debug(iter.nextElement());
// Only the roles from the DatabaseServerLoginModule should exist
assertTrue("Role1 is NOT a role", !roles.isMember(new SimplePrincipal("Role1")));
assertTrue("Role2 is NOT a role", !roles.isMember(new SimplePrincipal("Role2")));
assertTrue("Role3 is a role", roles.isMember(new SimplePrincipal("Role3")));
assertTrue("Role4 is a role", roles.isMember(new SimplePrincipal("Role4")));
lc.logout();
}
finally
{
conn.close();
}
}
public void testCertLogin() throws Exception
{
log.info("testCertLogin");
InitialContext ctx = new InitialContext();
ctx.rebind("testCertLogin", new TestSecurityDomain());
KeyStore store = KeyStore.getInstance("JKS");
ClassLoader loader = Thread.currentThread().getContextClassLoader();
URL resURL = loader.getResource("security/tst.keystore");
store.load(resURL.openStream(), "unit-tests".toCharArray());
X509Certificate cert = (X509Certificate) store.getCertificate("unit-tests");
SimplePrincipal x509 = new SimplePrincipal("unit-tests");
SecurityAssociationHandler handler = new SecurityAssociationHandler(x509, cert);
LoginContext lc = new LoginContext("testCertLogin", handler);
lc.login();
Subject subject = lc.getSubject();
assertTrue("Principals contains unit-tests", subject.getPrincipals().contains(new SimplePrincipal("unit-tests")));
assertTrue("Principals contains x509cert",
subject.getPublicCredentials().contains(cert));
}
public void testCertRoles() throws Exception
{
log.info("testCertRoles");
InitialContext ctx = new InitialContext();
ctx.rebind("testCertRoles", new TestSecurityDomain());
KeyStore store = KeyStore.getInstance("JKS");
ClassLoader loader = Thread.currentThread().getContextClassLoader();
URL resURL = loader.getResource("security/tst.keystore");
store.load(resURL.openStream(), "unit-tests".toCharArray());
X509Certificate cert = (X509Certificate) store.getCertificate("unit-tests");
SimplePrincipal x509 = new SimplePrincipal("unit-tests");
SecurityAssociationHandler handler = new SecurityAssociationHandler(x509, cert);
LoginContext lc = new LoginContext("testCertRoles", handler);
lc.login();
Subject subject = lc.getSubject();
Set groups = subject.getPrincipals(Group.class);
assertTrue("Principals contains unit-tests", subject.getPrincipals().contains(new SimplePrincipal("unit-tests")));
assertTrue("Principals contains Roles", groups.contains(new SimplePrincipal("Roles")));
assertTrue("Principals contains x509cert",
subject.getPublicCredentials().contains(cert));
Group roles = (Group) groups.iterator().next();
Iterator groupsIter = groups.iterator();
while( groupsIter.hasNext() )
{
roles = (Group) groupsIter.next();
if( roles.getName().equals("Roles") )
{
assertTrue("CertUser is a role", roles.isMember(new SimplePrincipal("CertUser")));
assertTrue("Java is NOT a role", roles.isMember(new SimplePrincipal("Java")) == false);
assertTrue("Coder is NOT a role", roles.isMember(new SimplePrincipal("Coder")) == false);
}
else if( roles.getName().equals("CallerPrincipal") )
{
log.info("CallerPrincipal is "+roles.members().nextElement());
boolean isMember = roles.isMember(new SimplePrincipal("callerX509"));
assertTrue("CallerPrincipal is callerX509", isMember);
}
}
lc.logout();
}
// Method to find the group named "Roles" in the given Set of groups.
private Group findRolesGroup(Set groups)
{
// Find the "Roles" group:
Iterator groupsIter = groups.iterator();
Group roles = null;
while (groupsIter.hasNext()) {
roles = (Group)groupsIter.next();
if (roles.getName().equals("Roles"))
break;
}
return roles;
}
private Connection setupLoginTables() throws Exception
{
Class.forName("org.hsqldb.jdbcDriver");
// Create a DataSource binding
TestDS ds = new TestDS();
InitialContext ctx = new InitialContext();
ctx.rebind("testJdbc", ds);
// Start database and setup tables
Connection conn = ds.getConnection("sa", "");
Statement statement = conn.createStatement();
createPrincipalsTable(statement);
createRolesTable(statement);
statement.close();
// no connection closing, if hsql is in process
// the database is disposed
return conn;
}
private void createPrincipalsTable(Statement statement) throws SQLException
{
try
{
statement.execute("DROP TABLE Principals");
}
catch(SQLException e)
{
// Ok, assume table does not exist
}
boolean result = statement.execute("CREATE TABLE Principals ("
+ "PrincipalID VARCHAR(64) PRIMARY KEY,"
+ "Password VARCHAR(64) )"
);
log.info("Created Principals table, result="+result);
result = statement.execute("INSERT INTO Principals VALUES ('scott', 'echoman')");
log.info("INSERT INTO Principals VALUES ('scott', 'echoman'), result="+result);
result = statement.execute("INSERT INTO Principals VALUES ('stark', 'javaman')");
log.info("INSERT INTO Principals VALUES ('stark', 'javaman'), result="+result);
// This differs from the users.properties jduke settings
result = statement.execute("INSERT INTO Principals VALUES ('jduke', 'jduke')");
log.info("INSERT INTO Principals VALUES ('jduke', 'jduke'), result="+result);
}
private void createRolesTable(Statement statement) throws SQLException
{
try
{
statement.execute("DROP TABLE Roles");
}
catch(SQLException e)
{
// Ok, assume table does not exist
}
boolean result = statement.execute("CREATE TABLE Roles ("
+ "PrincipalID VARCHAR(64),"
+ "Role VARCHAR(64),"
+ "RoleGroup VARCHAR(64) )"
);
log.info("Created Roles table, result="+result);
result = statement.execute("INSERT INTO Roles VALUES ('scott', 'Echo', 'Roles')");
log.info("INSERT INTO Roles VALUES ('scott', 'Echo', 'Roles'), result="+result);
result = statement.execute("INSERT INTO Roles VALUES ('scott', 'callerScott', 'CallerPrincipal')");
log.info("INSERT INTO Roles VALUES ('scott', 'callerScott', 'CallerPrincipal'), result="+result);
result = statement.execute("INSERT INTO Roles VALUES ('stark', 'Java', 'Roles')");
log.info("INSERT INTO Roles VALUES ('stark', 'Java', 'Roles'), result="+result);
result = statement.execute("INSERT INTO Roles VALUES ('stark', 'Coder', 'Roles')");
log.info("INSERT INTO Roles VALUES ('stark', 'Coder', 'Roles'), result="+result);
result = statement.execute("INSERT INTO Roles VALUES ('stark', 'callerStark', 'CallerPrincipal')");
log.info("INSERT INTO Roles VALUES ('stark', 'callerStark', 'CallerPrincipal'), result="+result);
result = statement.execute("INSERT INTO Roles VALUES ('jduke', 'Role3', 'Roles')");
log.info("INSERT INTO Roles VALUES ('jduke', 'Role3', 'Roles'), result="+result);
result = statement.execute("INSERT INTO Roles VALUES ('jduke', 'Role4', 'Roles')");
log.info("INSERT INTO Roles VALUES ('jduke', 'Role4', 'Roles'), result="+result);
}
public static void main(java.lang.String[] args)
{
// Print the location of the users.properties resource
java.net.URL users = LoginModulesUnitTestCase.class.getResource("/users.properties");
System.out.println("users.properties is here: "+users);
TestSuite suite = new TestSuite(LoginModulesUnitTestCase.class);
junit.textui.TestRunner.run(suite);
}
}