[jboss-cvs] JBoss Messaging SVN: r5889 - in trunk: tests/src/org/jboss/messaging/tests/unit/core/security/impl and 1 other directory.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Wed Feb 18 05:21:15 EST 2009
Author: jmesnil
Date: 2009-02-18 05:21:15 -0500 (Wed, 18 Feb 2009)
New Revision: 5889
Added:
trunk/src/main/org/jboss/messaging/integration/security/JAASSecurityManager.java
trunk/tests/src/org/jboss/messaging/tests/unit/core/security/impl/JAASSecurityManagerTest.java
Log:
JBMESSAGING-1326: JAASSecurityManager
* added a JAASSecurityManager (using only JAAS API)
Added: trunk/src/main/org/jboss/messaging/integration/security/JAASSecurityManager.java
===================================================================
--- trunk/src/main/org/jboss/messaging/integration/security/JAASSecurityManager.java (rev 0)
+++ trunk/src/main/org/jboss/messaging/integration/security/JAASSecurityManager.java 2009-02-18 10:21:15 UTC (rev 5889)
@@ -0,0 +1,285 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * 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.messaging.integration.security;
+
+import static org.jboss.messaging.core.security.CheckType.CREATE;
+import static org.jboss.messaging.core.security.CheckType.READ;
+import static org.jboss.messaging.core.security.CheckType.WRITE;
+
+import java.security.Principal;
+import java.security.acl.Group;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+
+import org.jboss.messaging.core.logging.Logger;
+import org.jboss.messaging.core.security.CheckType;
+import org.jboss.messaging.core.security.JBMSecurityManager;
+import org.jboss.messaging.core.security.Role;
+import org.jboss.messaging.core.server.MessagingComponent;
+
+/**
+ * This implementation delegates to the JAAS security interfaces.
+ *
+ * @author <a href="ataylor at redhat.com">Andy Taylor</a>
+ * @author <a href="tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="jmesnil at redhat.com">Jeff Mesnil</a>
+ * @author <a href="on at ibis.odessa.ua">Oleg Nitz</a>
+ * @author Scott.Stark at jboss.org
+ */
+public class JAASSecurityManager implements JBMSecurityManager, MessagingComponent
+{
+ private static final Logger log = Logger.getLogger(JAASSecurityManager.class);
+
+ // Static --------------------------------------------------------
+
+ // Attributes ----------------------------------------------------
+
+ private boolean trace = log.isTraceEnabled();
+
+ private String configurationName;
+
+ private boolean started;
+
+ private CallbackHandler callbackHandler;
+
+ private Configuration config;
+
+ // JBMSecurityManager implementation -----------------------------
+
+ public boolean validateUser(final String user, final String password)
+ {
+ try
+ {
+ getAuthenticatedSubject(user, password);
+ return true;
+ }
+ catch (LoginException e1)
+ {
+ return false;
+ }
+ }
+
+ public boolean validateUserAndRole(final String user,
+ final String password,
+ final Set<Role> roles,
+ final CheckType checkType)
+ {
+ Subject localSubject = null;
+ try
+ {
+ localSubject = getAuthenticatedSubject(user, password);
+ }
+ catch (LoginException e1)
+ {
+ return false;
+ }
+
+ boolean authenticated = true;
+
+ if (localSubject != null)
+ {
+ Set<Principal> rolePrincipals = getRolePrincipals(checkType, roles);
+
+ // authenticated = realmMapping.doesUserHaveRole(principal, rolePrincipals);
+
+ boolean hasRole = false;
+ // check that the caller is authenticated to the current thread
+
+ // Check the caller's roles
+ Group subjectRoles = getSubjectRoles(localSubject);
+ if (subjectRoles != null)
+ {
+ Iterator<Principal> iter = rolePrincipals.iterator();
+ while (!hasRole && iter.hasNext())
+ {
+ Principal role = iter.next();
+ hasRole = subjectRoles.isMember(role);
+ }
+ }
+
+ authenticated = hasRole;
+
+ if (trace)
+ {
+ log.trace("user " + user + (authenticated ? " is " : " is NOT ") + "authorized");
+ }
+ }
+ return authenticated;
+ }
+
+ // MessagingComponent implementation -----------------------------
+
+ /**
+ * lifecycle method, needs to be called
+ *
+ * @throws Exception
+ */
+ public synchronized void start() throws Exception
+ {
+ if (started)
+ {
+ return;
+ }
+
+ started = true;
+ }
+
+ public synchronized void stop()
+ {
+ if (!started)
+ {
+ return;
+ }
+ started = false;
+ }
+
+ public synchronized boolean isStarted()
+ {
+ return started;
+ }
+
+ private Subject getAuthenticatedSubject(final String user, final String password) throws LoginException
+ {
+ SimplePrincipal principal = user == null ? null : new SimplePrincipal(user);
+
+ char[] passwordChars = null;
+
+ if (password != null)
+ {
+ passwordChars = password.toCharArray();
+ }
+
+ Subject subject = new Subject();
+
+ subject.getPrincipals().add(principal);
+ subject.getPrivateCredentials().add(passwordChars);
+
+ LoginContext lc = new LoginContext(configurationName, subject, callbackHandler, config);
+ lc.login();
+ return lc.getSubject();
+ }
+
+ private Group getSubjectRoles(Subject subject)
+ {
+ Set<Group> subjectGroups = subject.getPrincipals(Group.class);
+ Iterator<Group> iter = subjectGroups.iterator();
+ Group roles = null;
+ while (iter.hasNext())
+ {
+ Group grp = iter.next();
+ String name = grp.getName();
+ if (name.equals("Roles"))
+ {
+ roles = grp;
+ }
+ }
+ return roles;
+ }
+
+ private Set<Principal> getRolePrincipals(final CheckType checkType, final Set<Role> roles)
+ {
+ Set<Principal> principals = new HashSet<Principal>();
+ for (Role role : roles)
+ {
+ if ((checkType.equals(CREATE) && role.isCheckType(CREATE))
+ || (checkType.equals(WRITE) && role.isCheckType(WRITE))
+ || (checkType.equals(READ) && role.isCheckType(READ)))
+ {
+ principals.add(new SimplePrincipal(role.getName()));
+ }
+ }
+ return principals;
+ }
+
+ // Public --------------------------------------------------------
+
+ public void setConfigurationName(String configurationName)
+ {
+ this.configurationName = configurationName;
+ }
+
+ public void setCallbackHandler(CallbackHandler handler)
+ {
+ this.callbackHandler = handler;
+ }
+
+ public void setConfiguration(Configuration config)
+ {
+ this.config = config;
+ }
+
+ // Private -------------------------------------------------------
+
+ // Inner classes -------------------------------------------------
+
+ public static class SimplePrincipal implements Principal, java.io.Serializable
+ {
+ private static final long serialVersionUID = 1L;
+
+ private String name;
+
+ public SimplePrincipal(String name)
+ {
+ this.name = name;
+ }
+
+ /** Compare this SimplePrincipal's name against another Principal
+ @return true if name equals another.getName();
+ */
+ public boolean equals(Object another)
+ {
+ if (!(another instanceof Principal))
+ return false;
+ String anotherName = ((Principal)another).getName();
+ boolean equals = false;
+ if (name == null)
+ equals = anotherName == null;
+ else
+ equals = name.equals(anotherName);
+ return equals;
+ }
+
+ public int hashCode()
+ {
+ return (name == null ? 0 : name.hashCode());
+ }
+
+ public String toString()
+ {
+ return name;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+ }
+
+}
Added: trunk/tests/src/org/jboss/messaging/tests/unit/core/security/impl/JAASSecurityManagerTest.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/unit/core/security/impl/JAASSecurityManagerTest.java (rev 0)
+++ trunk/tests/src/org/jboss/messaging/tests/unit/core/security/impl/JAASSecurityManagerTest.java 2009-02-18 10:21:15 UTC (rev 5889)
@@ -0,0 +1,198 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * 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.messaging.tests.unit.core.security.impl;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.security.acl.Group;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
+import javax.security.auth.spi.LoginModule;
+
+import junit.framework.TestCase;
+
+import org.jboss.messaging.core.security.CheckType;
+import org.jboss.messaging.core.security.Role;
+import org.jboss.messaging.integration.security.JAASSecurityManager;
+import org.jboss.security.SimpleGroup;
+
+/**
+ * tests the JAASSecurityManager
+ *
+ *@author <a href="jmesnil at redhat.com">Jeff Mesnil</a>
+ */
+public class JAASSecurityManagerTest extends TestCase
+{
+ private JAASSecurityManager securityManager;
+
+ private static final String USER = "user";
+ private static final String PASSWORD = "password";
+ private static final String INVALID_PASSWORD = "invalidPassword";
+ private static final String ROLE = "role";
+ private static final String INVALID_ROLE = "invalidRole";
+
+ protected void setUp() throws Exception
+ {
+ securityManager = new JAASSecurityManager();
+
+ final String domainName = SimpleLogingModule.class.getName();
+ // pass the correct user/pass and a role as options to the login module
+ final Map<String, String> options = new HashMap<String, String>();
+ options.put("user", USER);
+ options.put("pass", PASSWORD);
+ options.put("role", ROLE);
+
+ securityManager.setConfigurationName(domainName);
+ securityManager.setCallbackHandler(new CallbackHandler()
+ {
+ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
+ {
+ // empty callback, auth info are directly passed as options to the login module
+ }
+ });
+ securityManager.setConfiguration(new SimpleConfiguration(domainName, options));
+
+ }
+
+ protected void tearDown() throws Exception
+ {
+ securityManager = null;
+ }
+
+ public void testValidatingUser()
+ {
+ assertTrue(securityManager.validateUser(USER, PASSWORD));
+ assertFalse(securityManager.validateUser(USER, INVALID_PASSWORD));
+ }
+
+ public void testValidatingUserAndRole()
+ {
+ Set<Role> roles = new HashSet<Role>();
+ roles.add(new Role(ROLE, true, true, true));
+
+ assertTrue(securityManager.validateUserAndRole(USER, PASSWORD, roles, CheckType.CREATE));
+
+ roles.clear();
+ roles.add(new Role(INVALID_ROLE, true, true, true));
+ assertFalse(securityManager.validateUserAndRole(USER, PASSWORD, roles, CheckType.CREATE));
+ }
+
+ public static class SimpleLogingModule implements LoginModule
+ {
+
+ private Map<String, ?> options;
+
+ private Subject subject;
+
+ public SimpleLogingModule()
+ {
+ }
+
+ public boolean abort() throws LoginException
+ {
+ return true;
+ }
+
+ public boolean commit() throws LoginException
+ {
+ return true;
+ }
+
+ public void initialize(Subject subject,
+ CallbackHandler callbackHandler,
+ Map<String, ?> sharedState,
+ Map<String, ?> options)
+ {
+ this.subject = subject;
+ this.options = options;
+ }
+
+ public boolean login() throws LoginException
+ {
+ Iterator<char[]> iterator = subject.getPrivateCredentials(char[].class).iterator();
+ char[] passwordChars = iterator.next();
+ String password = new String(passwordChars);
+ Iterator<Principal> iterator2 = subject.getPrincipals().iterator();
+ String user = iterator2.next().getName();
+
+ boolean authenticated = user.equals(options.get("user")) && password.equals(options.get("pass"));
+
+ if (authenticated)
+ {
+ Group roles = new SimpleGroup("Roles");
+ roles.addMember(new JAASSecurityManager.SimplePrincipal((String)options.get("role")));
+ subject.getPrincipals().add(roles);
+ }
+ return authenticated;
+
+ }
+
+ public Subject getSubject()
+ {
+ return subject;
+ }
+
+ public boolean logout() throws LoginException
+ {
+ return true;
+ }
+ }
+
+ public static class SimpleConfiguration extends Configuration
+ {
+ private Map<String, ?> options;
+ private String loginModuleName;
+
+ public SimpleConfiguration(String loginModuleName, Map<String, ?> options)
+ {
+ this.loginModuleName = loginModuleName;
+ this.options = options;
+ }
+
+ @Override
+ public AppConfigurationEntry[] getAppConfigurationEntry(String name)
+ {
+ AppConfigurationEntry entry = new AppConfigurationEntry(loginModuleName,
+ LoginModuleControlFlag.REQUIRED,
+ options);
+ return new AppConfigurationEntry[] { entry };
+ }
+
+ @Override
+ public void refresh()
+ {
+ }
+ }
+}
More information about the jboss-cvs-commits
mailing list