001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.test.security.test;
023:
024: import java.util.Arrays;
025: import java.util.Map;
026: import java.util.Iterator;
027: import java.util.Set;
028: import java.io.File;
029: import java.io.FileWriter;
030: import java.io.InputStream;
031: import java.io.InputStreamReader;
032: import java.security.acl.Group;
033:
034: import javax.management.MBeanServer;
035: import javax.management.MBeanServerBuilder;
036: import javax.management.MBeanServerFactory;
037: import javax.resource.spi.security.PasswordCredential;
038: import javax.security.auth.login.Configuration;
039: import javax.security.auth.login.AppConfigurationEntry;
040: import javax.security.auth.login.LoginContext;
041: import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
042: import javax.security.auth.Subject;
043:
044: import org.apache.log4j.Logger;
045:
046: import org.jboss.logging.XLevel;
047: import org.jboss.security.auth.login.XMLLoginConfigImpl;
048: import org.jboss.security.auth.spi.Users;
049: import org.jboss.security.auth.login.LoginConfigObjectModelFactory;
050: import org.jboss.security.auth.login.PolicyConfig;
051: import org.jboss.security.auth.login.AuthenticationInfo;
052: import org.jboss.security.auth.spi.UsersObjectModelFactory;
053: import org.jboss.security.auth.callback.UsernamePasswordHandler;
054: import org.jboss.security.SimplePrincipal;
055: import org.jboss.security.Util;
056: import org.jboss.util.StringPropertyReplacer;
057: import org.jboss.xb.binding.Unmarshaller;
058: import org.jboss.xb.binding.UnmarshallerFactory;
059: import org.jboss.xb.binding.sunday.unmarshalling.DefaultSchemaResolver;
060:
061: /**
062: * Tests of the LoginModule classes using the XMLLoginConfigImpl implementation
063: * of the JAAS login module configuration.
064: * @author Scott.Stark@jboss.org
065: * @version $Revision: 59906 $
066: */
067: public class XMLLoginModulesUnitTestCase extends
068: LoginModulesUnitTestCase {
069:
070: public XMLLoginModulesUnitTestCase(String name) {
071: super (name);
072: }
073:
074: protected void setUp() throws Exception {
075: // Setup the replacement properties
076: System.setProperty("users.properties",
077: "/security/config/users.properites");
078: System.setProperty("roles.properties",
079: "/security/config/roles.properites");
080:
081: // Install the custom JAAS configuration
082: XMLLoginConfigImpl config = new XMLLoginConfigImpl();
083: config.setConfigResource("security/login-config.xml");
084: config.loadConfig();
085: Configuration.setConfiguration(config);
086:
087: // Turn on trace level logging
088: Logger root = Logger.getRootLogger();
089: root.setLevel(XLevel.TRACE);
090: }
091:
092: public void testGargantusRealm() throws Exception {
093: Configuration config = Configuration.getConfiguration();
094: AppConfigurationEntry[] entries = config
095: .getAppConfigurationEntry("testGargantusRealm");
096: assertTrue("entries.length == 1", entries.length == 1);
097: AppConfigurationEntry entry = entries[0];
098: LoginModuleControlFlag flag = entry.getControlFlag();
099: assertTrue("flag == required",
100: flag == LoginModuleControlFlag.REQUIRED);
101: Map options = entry.getOptions();
102: String principal = (String) options.get("principal");
103: assertTrue("principal(" + principal + ") = sa", principal
104: .equals("sa"));
105: String userName = (String) options.get("userName");
106: assertTrue("userName(" + userName + ") = sa", userName
107: .equals("sa"));
108: String password = (String) options.get("password");
109: assertTrue("password(" + password + ") = ''", password
110: .equals(""));
111: String managedConnectionFactoryName = (String) options
112: .get("managedConnectionFactoryName");
113: assertTrue(
114: "managedConnectionFactoryName("
115: + managedConnectionFactoryName + ") = ''",
116: managedConnectionFactoryName
117: .equals("jboss.jca:service=LocalTxCM,name=DefaultDS"));
118: }
119:
120: public void testPropertyReplacement() throws Exception {
121: Configuration config = Configuration.getConfiguration();
122: AppConfigurationEntry[] entries = config
123: .getAppConfigurationEntry("testPropertyReplacement");
124: assertTrue("entries.length == 1", entries.length == 1);
125: AppConfigurationEntry entry = entries[0];
126: LoginModuleControlFlag flag = entry.getControlFlag();
127: assertTrue("flag == required",
128: flag == LoginModuleControlFlag.REQUIRED);
129: Map options = entry.getOptions();
130: String users = (String) options.get("usersProperties");
131: assertTrue("usersProperties(" + users
132: + ") = /security/config/users.properites", users
133: .equals("/security/config/users.properites"));
134: String roles = (String) options.get("rolesProperties");
135: assertTrue("rolesProperties(" + roles
136: + ") = /security/config/roles.properites", roles
137: .equals("/security/config/roles.properites"));
138: }
139:
140: public void testPBEIdentityLoginModule() throws Exception {
141: // Create our own MBeanServer
142: MBeanServer server = MBeanServerFactory
143: .createMBeanServer("jboss");
144: getLog().info("testPBEIdentityLoginModule");
145: // Login using the testPBEIdentityLoginModuleTmpFilePassword config
146: UsernamePasswordHandler handler = new UsernamePasswordHandler(
147: "sa", "thesecret".toCharArray());
148: LoginContext lc = new LoginContext(
149: "testPBEIdentityLoginModule", handler);
150: lc.login();
151: Subject subject = lc.getSubject();
152: Set pcs = subject
153: .getPrivateCredentials(PasswordCredential.class);
154: assertEquals("PasswordCredential", 1, pcs.size());
155: PasswordCredential pc = (PasswordCredential) pcs.iterator()
156: .next();
157: assertEquals("PasswordCredential.sa", "sa", pc.getUserName());
158: assertEquals("PasswordCredential.password", "thesecret",
159: new String(pc.getPassword()));
160: lc.logout();
161: MBeanServerFactory.releaseMBeanServer(server);
162: }
163:
164: public void testPBEIdentityLoginModuleTmpFilePassword()
165: throws Exception {
166: // Create a tmp password file for TmpFilePassword
167: File tmpPassword = new File(System
168: .getProperty("java.io.tmpdir"), "tmp.password");
169: FileWriter writer = new FileWriter(tmpPassword);
170: writer.write("testPBEIdentityLoginModuleTmpFilePassword");
171: writer.close();
172:
173: // Create our own MBeanServer
174: MBeanServer server = MBeanServerFactory
175: .createMBeanServer("jboss");
176: getLog().info("testPBEIdentityLoginModuleTmpFilePassword");
177: // Login using the testPBEIdentityLoginModuleTmpFilePassword config
178: UsernamePasswordHandler handler = new UsernamePasswordHandler(
179: "sa", "thesecret2".toCharArray());
180: LoginContext lc = new LoginContext(
181: "testPBEIdentityLoginModuleTmpFilePassword", handler);
182: lc.login();
183: Subject subject = lc.getSubject();
184: Set pcs = subject
185: .getPrivateCredentials(PasswordCredential.class);
186: assertEquals("PasswordCredential", 1, pcs.size());
187: PasswordCredential pc = (PasswordCredential) pcs.iterator()
188: .next();
189: assertEquals("PasswordCredential.sa", "sa", pc.getUserName());
190: assertEquals("PasswordCredential.password", "thesecret2",
191: new String(pc.getPassword()));
192: lc.logout();
193: MBeanServerFactory.releaseMBeanServer(server);
194: tmpPassword.delete();
195: }
196:
197: /**
198: * @throws Exception
199: */
200: public void testXmlLoginModuleParsing() throws Exception {
201: LoginConfigObjectModelFactory lcomf = new LoginConfigObjectModelFactory();
202: UsersObjectModelFactory uomf = new UsersObjectModelFactory();
203:
204: InputStream is = Thread.currentThread().getContextClassLoader()
205: .getResourceAsStream("security/login-config2.xml");
206: InputStreamReader xmlReader = new InputStreamReader(is);
207: Unmarshaller unmarshaller = UnmarshallerFactory.newInstance()
208: .newUnmarshaller();
209: unmarshaller.mapFactoryToNamespace(uomf,
210: "http://www.jboss.org/j2ee/schemas/XMLLoginModule");
211: PolicyConfig config = (PolicyConfig) unmarshaller.unmarshal(
212: xmlReader, lcomf, null);
213: AuthenticationInfo info = config.get("testXMLLoginModule");
214: assertTrue("test-xml-config != null", info != null);
215: AppConfigurationEntry[] entries = info
216: .getAppConfigurationEntry();
217: assertTrue("entries.length == 1", entries.length == 1);
218: AppConfigurationEntry ace = entries[0];
219: assertTrue("org.jboss.security.auth.spi.XMLLoginModule", ace
220: .getLoginModuleName().equals(
221: "org.jboss.security.auth.spi.XMLLoginModule"));
222: Map options = ace.getOptions();
223: assertTrue("Options.size == 2", options.size() == 2);
224: String guest = (String) options.get("unauthenticatedIdentity");
225: assertTrue("guest", guest.equals("guest"));
226: Users users = (Users) options.get("userInfo");
227: Users.User user = users.getUser("jdukeman");
228: String name = user.getName();
229: assertTrue("name == jdukeman", name.equals("jdukeman"));
230: String passwrd = user.getPassword();
231: assertTrue("passwrd == anotherduke", passwrd
232: .equals("anotherduke"));
233: String[] roleNames = user.getRoleNames();
234: assertTrue("roles in (Role2, Role3)", roleNames[0]
235: .equals("Role2")
236: && roleNames[1].equals("Role3"));
237:
238: // Test that
239: AuthenticationInfo testNoModuleOptions = config
240: .get("testNoModuleOptions");
241: assertTrue("testNoModuleOptions != null",
242: testNoModuleOptions != null);
243: AppConfigurationEntry[] testNoModuleOptionsEntries = testNoModuleOptions
244: .getAppConfigurationEntry();
245: assertTrue("entries.length == 1",
246: testNoModuleOptionsEntries.length == 1);
247: AppConfigurationEntry testNoModuleOptionsACE = testNoModuleOptionsEntries[0];
248: assertTrue("org.jboss.security.auth.spi.XMLLoginModule",
249: testNoModuleOptionsACE.getLoginModuleName().equals(
250: "org.jboss.security.auth.spi.XMLLoginModule"));
251: Map testNoModuleOptionsMap = testNoModuleOptionsACE
252: .getOptions();
253: assertTrue("testNoModuleOptionsMap.size("
254: + testNoModuleOptionsMap + ") == 0",
255: testNoModuleOptionsMap.size() == 0);
256: }
257:
258: public void testXMLLoginModule() throws Exception {
259: // Install the custom JAAS configuration
260: XMLLoginConfigImpl config = new XMLLoginConfigImpl();
261: config.setConfigResource("security/login-config2.xml");
262: config.loadConfig();
263: Configuration.setConfiguration(config);
264:
265: getLog().info("testXMLLoginModule");
266: UsernamePasswordHandler handler = new UsernamePasswordHandler(
267: "scott", "echoman".toCharArray());
268: LoginContext lc = new LoginContext("testXMLLoginModule",
269: handler);
270: lc.login();
271: Subject subject = lc.getSubject();
272: Set groups = subject.getPrincipals(Group.class);
273: assertTrue("Principals contains scott", subject.getPrincipals()
274: .contains(new SimplePrincipal("scott")));
275: assertTrue("Principals contains Roles", groups
276: .contains(new SimplePrincipal("Roles")));
277: assertTrue("Principals contains CallerPrincipal", groups
278: .contains(new SimplePrincipal("CallerPrincipal")));
279: Group roles = (Group) groups.iterator().next();
280: Iterator groupsIter = groups.iterator();
281: while (groupsIter.hasNext()) {
282: roles = (Group) groupsIter.next();
283: if (roles.getName().equals("Roles")) {
284: assertTrue("Echo is a role", roles
285: .isMember(new SimplePrincipal("Echo")));
286: assertTrue("Java is NOT a role", roles
287: .isMember(new SimplePrincipal("Java")) == false);
288: assertTrue(
289: "Coder is NOT a role",
290: roles.isMember(new SimplePrincipal("Coder")) == false);
291: } else if (roles.getName().equals("CallerPrincipal")) {
292: getLog().info(
293: "CallerPrincipal is "
294: + roles.members().nextElement());
295: boolean isMember = roles.isMember(new SimplePrincipal(
296: "callerScott"));
297: assertTrue("CallerPrincipal is callerScott", isMember);
298: }
299: }
300: lc.logout();
301:
302: handler = new UsernamePasswordHandler("stark", "javaman"
303: .toCharArray());
304: lc = new LoginContext("testXMLLoginModule", handler);
305: lc.login();
306: subject = lc.getSubject();
307: groups = subject.getPrincipals(Group.class);
308: assertTrue("Principals contains stark", subject.getPrincipals()
309: .contains(new SimplePrincipal("stark")));
310: assertTrue("Principals contains Roles", groups
311: .contains(new SimplePrincipal("Roles")));
312: assertTrue("Principals contains CallerPrincipal", groups
313: .contains(new SimplePrincipal("CallerPrincipal")));
314: groupsIter = groups.iterator();
315: while (groupsIter.hasNext()) {
316: roles = (Group) groupsIter.next();
317: if (roles.getName().equals("Roles")) {
318: assertTrue("Echo is NOT a role", roles
319: .isMember(new SimplePrincipal("Echo")) == false);
320: assertTrue("Java is a role", roles
321: .isMember(new SimplePrincipal("Java")));
322: assertTrue("Coder is a role", roles
323: .isMember(new SimplePrincipal("Coder")));
324: } else if (roles.getName().equals("CallerPrincipal")) {
325: getLog().info(
326: "CallerPrincipal is "
327: + roles.members().nextElement());
328: boolean isMember = roles.isMember(new SimplePrincipal(
329: "callerStark"));
330: assertTrue("CallerPrincipal is callerStark", isMember);
331: }
332: }
333: lc.logout();
334:
335: // Test the usernames with common prefix
336: getLog().info("Testing similar usernames");
337: handler = new UsernamePasswordHandler("jdukeman", "anotherduke"
338: .toCharArray());
339: lc = new LoginContext("testXMLLoginModule", handler);
340: lc.login();
341: subject = lc.getSubject();
342: groups = subject.getPrincipals(Group.class);
343: assertTrue("Principals contains jdukeman", subject
344: .getPrincipals().contains(
345: new SimplePrincipal("jdukeman")));
346: assertTrue("Principals contains Roles", groups
347: .contains(new SimplePrincipal("Roles")));
348: assertTrue("Principals contains CallerPrincipal", groups
349: .contains(new SimplePrincipal("CallerPrincipal")));
350: groupsIter = groups.iterator();
351: while (groupsIter.hasNext()) {
352: roles = (Group) groupsIter.next();
353: if (roles.getName().equals("Roles")) {
354: assertTrue(
355: "Role1 is NOT a role",
356: roles.isMember(new SimplePrincipal("Role1")) == false);
357: assertTrue("Role2 is a role", roles
358: .isMember(new SimplePrincipal("Role2")));
359: assertTrue("Role3 is a role", roles
360: .isMember(new SimplePrincipal("Role3")));
361: } else if (roles.getName().equals("CallerPrincipal")) {
362: getLog().info(
363: "CallerPrincipal is "
364: + roles.members().nextElement());
365: boolean isMember = roles.isMember(new SimplePrincipal(
366: "callerJdukeman"));
367: assertTrue("CallerPrincipal is callerJdukeman",
368: isMember);
369: }
370: }
371: lc.logout();
372: }
373:
374: /**
375: * JBAS-2702
376: * @throws Exception
377: */
378: public void testXmlLoginModuleJaxbParsing() throws Exception {
379: UsersObjectModelFactory uomf = new UsersObjectModelFactory();
380:
381: InputStream is = Thread.currentThread().getContextClassLoader()
382: .getResourceAsStream("security/login-config3.xml");
383: InputStreamReader xmlReader = new InputStreamReader(is);
384:
385: DefaultSchemaResolver resolver = new DefaultSchemaResolver();
386:
387: Unmarshaller unmarshaller = UnmarshallerFactory.newInstance()
388: .newUnmarshaller();
389: unmarshaller.mapFactoryToNamespace(uomf,
390: "http://www.jboss.org/j2ee/schemas/XMLLoginModule");
391: PolicyConfig config = (PolicyConfig) unmarshaller.unmarshal(
392: xmlReader, resolver);
393: assertNotNull(config);
394:
395: }
396: }
|