[jboss-cvs] JBossAS SVN: r69795 - in trunk/messaging/src: main/org/jboss/jms/server/jbosssx and 1 other directory.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Tue Feb 12 08:17:45 EST 2008
Author: anil.saldhana at jboss.com
Date: 2008-02-12 08:17:45 -0500 (Tue, 12 Feb 2008)
New Revision: 69795
Added:
trunk/messaging/src/main/org/jboss/jms/server/jbosssx/JBossASSecurityMetadataStore.java
trunk/messaging/src/main/org/jboss/jms/server/jbosssx/JBossASSecurityMetadataStoreMBean.java
trunk/messaging/src/main/org/jboss/jms/server/jbosssx/SecurityActions.java
Modified:
trunk/messaging/src/etc/deploy/common/messaging-service.xml
Log:
JBAS-5230: SecurityMetaDataStore implementation for AS integration
Modified: trunk/messaging/src/etc/deploy/common/messaging-service.xml
===================================================================
--- trunk/messaging/src/etc/deploy/common/messaging-service.xml 2008-02-12 13:07:14 UTC (rev 69794)
+++ trunk/messaging/src/etc/deploy/common/messaging-service.xml 2008-02-12 13:17:45 UTC (rev 69795)
@@ -7,7 +7,7 @@
-->
<server>
- <mbean code="org.jboss.jms.server.security.SecurityMetadataStore"
+ <mbean code="org.jboss.jms.server.jbosssx.JBossASSecurityMetadataStore"
name="jboss.messaging:service=SecurityStore">
<attribute name="DefaultSecurityConfig">
Added: trunk/messaging/src/main/org/jboss/jms/server/jbosssx/JBossASSecurityMetadataStore.java
===================================================================
--- trunk/messaging/src/main/org/jboss/jms/server/jbosssx/JBossASSecurityMetadataStore.java (rev 0)
+++ trunk/messaging/src/main/org/jboss/jms/server/jbosssx/JBossASSecurityMetadataStore.java 2008-02-12 13:17:45 UTC (rev 69795)
@@ -0,0 +1,320 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, 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.jms.server.jbosssx;
+
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jms.JMSSecurityException;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.security.auth.Subject;
+
+import org.jboss.jms.server.SecurityStore;
+import org.jboss.jms.server.security.CheckType;
+import org.jboss.jms.server.security.SecurityMetadata;
+import org.jboss.logging.Logger;
+import org.jboss.security.AuthenticationManager;
+import org.jboss.security.RealmMapping;
+import org.jboss.security.SimplePrincipal;
+import org.jboss.security.SubjectSecurityManager;
+import org.w3c.dom.Element;
+
+/**
+ * A security metadate store for JMS. Stores security information for destinations and delegates
+ * authentication and authorization to a JaasSecurityManager.
+ *
+ * @author Peter Antman
+ * @author <a href="mailto:Scott.Stark at jboss.org">Scott Stark</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:ovidiu at feodorov.com">Ovidiu Feodorov</a>
+ * @version $Revision$
+ *
+ * $Id$
+ */
+public class JBossASSecurityMetadataStore implements SecurityStore, JBossASSecurityMetadataStoreMBean
+{
+ // Constants -----------------------------------------------------
+
+ private static final Logger log = Logger.getLogger(JBossASSecurityMetadataStore.class);
+
+ public static final String DEFAULT_SUCKER_USER_PASSWORD = "CHANGE ME!!";
+
+ // Attributes ----------------------------------------------------
+
+ private boolean trace = log.isTraceEnabled();
+
+ private Map queueSecurityConf;
+ private Map topicSecurityConf;
+
+ private AuthenticationManager authenticationManager;
+ private RealmMapping realmMapping;
+
+ private Element defaultSecurityConfig;
+ private String securityDomain = "java:/jaas/messaging";
+
+ private String suckerPassword;
+
+ // Static --------------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ public JBossASSecurityMetadataStore()
+ {
+ queueSecurityConf = new HashMap();
+ topicSecurityConf = new HashMap();
+ }
+
+ // SecurityManager implementation --------------------------------
+
+ public SecurityMetadata getSecurityMetadata(boolean isQueue, String destName)
+ {
+ SecurityMetadata m = (SecurityMetadata)
+ (isQueue ? queueSecurityConf.get(destName) : topicSecurityConf.get(destName));
+
+ if (m == null)
+ {
+ // No SecurityMetadata was configured for the destination, apply the default
+ if (defaultSecurityConfig != null)
+ {
+ log.debug("No SecurityMetadadata was available for " + destName + ", using default security config");
+ try
+ {
+ m = new SecurityMetadata(defaultSecurityConfig);
+ }
+ catch (Exception e)
+ {
+ log.warn("Unable to apply default security for destName, using guest " + destName, e);
+ m = new SecurityMetadata();
+ }
+ }
+ else
+ {
+ // default to guest
+ log.warn("No SecurityMetadadata was available for " + destName + ", adding guest");
+ m = new SecurityMetadata();
+ }
+
+ // don't cache it! this way the callers will be able to take advantage of default security
+ // configuration updates
+ // securityConf.put(destName, m);
+ }
+ return m;
+ }
+
+ public void setSecurityConfig(boolean isQueue, String destName, Element conf) throws Exception
+ {
+ if (trace) { log.trace("adding security configuration for " + (isQueue ? "queue " : "topic ") + destName); }
+
+ if (conf == null)
+ {
+ clearSecurityConfig(isQueue, destName);
+ }
+ else
+ {
+ SecurityMetadata m = new SecurityMetadata(conf);
+
+ if (isQueue)
+ {
+ queueSecurityConf.put(destName, m);
+ }
+ else
+ {
+ topicSecurityConf.put(destName, m);
+ }
+ }
+ }
+
+ public void clearSecurityConfig(boolean isQueue, String name) throws Exception
+ {
+ if (trace) { log.trace("clearing security configuration for " + (isQueue ? "queue " : "topic ") + name); }
+
+ if (isQueue)
+ {
+ queueSecurityConf.remove(name);
+ }
+ else
+ {
+ topicSecurityConf.remove(name);
+ }
+ }
+
+ public Subject authenticate(String user, String password) throws JMSSecurityException
+ {
+ if (trace) { log.trace("authenticating user " + user); }
+
+ SimplePrincipal principal = new SimplePrincipal(user);
+ char[] passwordChars = null;
+ if (password != null)
+ {
+ passwordChars = password.toCharArray();
+ }
+
+ Subject subject = new Subject();
+
+ boolean authenticated = false;
+
+ if (SUCKER_USER.equals(user))
+ {
+ if (trace) { log.trace("Authenticating sucker user"); }
+
+ checkDefaultSuckerPassword(password);
+
+ // The special user SUCKER_USER is used for creating internal connections that suck messages between nodes
+
+ authenticated = suckerPassword.equals(password);
+ }
+ else
+ {
+ authenticated = authenticationManager.isValid(principal, passwordChars, subject);
+ }
+
+ if (authenticated)
+ {
+ // Warning! This "taints" thread local. Make sure you pop it off the stack as soon as
+ // you're done with it.
+ SecurityActions.pushSubjectContext(principal, passwordChars, subject,
+ authenticationManager.getSecurityDomain());
+ return subject;
+ }
+ else
+ {
+ throw new JMSSecurityException("User " + user + " is NOT authenticated");
+ }
+ }
+
+ public boolean authorize(String user, Set rolePrincipals, CheckType checkType)
+ {
+ if (trace) { log.trace("authorizing user " + user + " for role(s) " + rolePrincipals.toString()); }
+
+ if (SUCKER_USER.equals(user))
+ {
+ //The special user SUCKER_USER is used for creating internal connections that suck messages between nodes
+ //It has automatic read/write access to all destinations
+ return (checkType.equals(CheckType.READ) || checkType.equals(CheckType.WRITE));
+ }
+
+ Principal principal = user == null ? null : new SimplePrincipal(user);
+
+ boolean hasRole = realmMapping.doesUserHaveRole(principal, rolePrincipals);
+
+ if (trace) { log.trace("user " + user + (hasRole ? " is " : " is NOT ") + "authorized"); }
+
+ return hasRole;
+ }
+
+ // Public --------------------------------------------------------
+
+ public void setSuckerPassword(String password)
+ {
+ checkDefaultSuckerPassword(password);
+
+ this.suckerPassword = password;
+ }
+
+ public void start() throws NamingException
+ {
+ if (trace) { log.trace("initializing SecurityMetadataStore"); }
+
+ // Get the JBoss security manager from JNDI
+ InitialContext ic = new InitialContext();
+
+ try
+ {
+ Object mgr = ic.lookup(securityDomain);
+
+ log.debug("JaasSecurityManager is " + mgr);
+
+ authenticationManager = (AuthenticationManager)mgr;
+ realmMapping = (RealmMapping)mgr;
+
+ log.trace("SecurityMetadataStore initialized");
+ }
+ catch (NamingException e)
+ {
+ // Apparently there is no security context, try adding java:/jaas
+ log.warn("Failed to lookup securityDomain " + securityDomain, e);
+
+ if (!securityDomain.startsWith("java:/jaas/"))
+ {
+ authenticationManager =
+ (SubjectSecurityManager)ic.lookup("java:/jaas/" + securityDomain);
+ }
+ else
+ {
+ throw e;
+ }
+ }
+ finally
+ {
+ ic.close();
+ }
+ }
+
+ public void stop() throws Exception
+ {
+ }
+
+ public String getSecurityDomain()
+ {
+ return this.securityDomain;
+ }
+
+ public void setSecurityDomain(String securityDomain)
+ {
+ this.securityDomain = securityDomain;
+ }
+
+ public Element getDefaultSecurityConfig()
+ {
+ return this.defaultSecurityConfig;
+ }
+
+ public void setDefaultSecurityConfig(Element conf) throws Exception
+ {
+ // Force a parse
+ new SecurityMetadata(conf);
+ defaultSecurityConfig = conf;
+ }
+
+ // Protected -----------------------------------------------------
+
+ // Package Private -----------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ private void checkDefaultSuckerPassword(String password)
+ {
+ // Sanity check
+ if (DEFAULT_SUCKER_USER_PASSWORD.equals(password))
+ {
+ log.warn("WARNING! POTENTIAL SECURITY RISK. It has been detected that the MessageSucker component " +
+ "which sucks messages from one node to another has not had its password changed from the installation default. " +
+ "Please see the JBoss Messaging user guide for instructions on how to do this.");
+ }
+ }
+
+ // Inner class ---------------------------------------------------
+
+}
Added: trunk/messaging/src/main/org/jboss/jms/server/jbosssx/JBossASSecurityMetadataStoreMBean.java
===================================================================
--- trunk/messaging/src/main/org/jboss/jms/server/jbosssx/JBossASSecurityMetadataStoreMBean.java (rev 0)
+++ trunk/messaging/src/main/org/jboss/jms/server/jbosssx/JBossASSecurityMetadataStoreMBean.java 2008-02-12 13:17:45 UTC (rev 69795)
@@ -0,0 +1,80 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, 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.jms.server.jbosssx;
+
+import java.security.Principal;
+import java.util.Set;
+
+import javax.jms.JMSSecurityException;
+import javax.security.auth.Subject;
+
+import org.jboss.jms.server.security.CheckType;
+import org.jboss.jms.server.security.SecurityMetadata;
+import org.w3c.dom.Element;
+
+/**
+ * The SecurityMetadataStore mbean interface
+ *
+ * @author Scott.Stark at jboss.org
+ * @version $Revision$
+ */
+public interface JBossASSecurityMetadataStoreMBean
+{
+ public String getSecurityDomain();
+ public void setSecurityDomain(String securityDomain);
+ public void setDefaultSecurityConfig(Element conf) throws Exception;
+ public Element getDefaultSecurityConfig();
+
+ public void setSuckerPassword(String password);
+ public void start() throws Exception;
+ public void stop() throws Exception;
+ /**
+ * @return the security meta-data for the given destination.
+ */
+ SecurityMetadata getSecurityMetadata(boolean isQueue, String destName);
+
+ void setSecurityConfig(boolean isQueue, String destName, Element conf) throws Exception;
+
+ void clearSecurityConfig(boolean isQueue, String name) throws Exception;
+
+ /**
+ * Authenticate the specified user with the given password. Implementations are most likely to
+ * delegates to a JBoss AuthenticationManager.
+ *
+ * Successful authentication will place a new SubjectContext on thread local, which will be used
+ * in the authorization process. However, we need to make sure we clean up thread local
+ * immediately after we used the information, otherwise some other people security my be screwed
+ * up, on account of thread local security stack being corrupted.
+ *
+ * @throws JMSSecurityException if the user is not authenticated
+ */
+ Subject authenticate(String user, String password) throws JMSSecurityException;
+
+ /**
+ * Authorize that the subject has at least one of the specified roles. Implementations are most
+ * likely to delegates to a JBoss AuthenticationManager.
+ *
+ * @param rolePrincipals - The set of roles allowed to read/write/create the destination.
+ * @return true if the subject is authorized, or false if not.
+ */
+ boolean authorize(String user, Set<Principal> rolePrincipals, CheckType checkType);
+}
\ No newline at end of file
Added: trunk/messaging/src/main/org/jboss/jms/server/jbosssx/SecurityActions.java
===================================================================
--- trunk/messaging/src/main/org/jboss/jms/server/jbosssx/SecurityActions.java (rev 0)
+++ trunk/messaging/src/main/org/jboss/jms/server/jbosssx/SecurityActions.java 2008-02-12 13:17:45 UTC (rev 69795)
@@ -0,0 +1,124 @@
+/*
+ * 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.jms.server.jbosssx;
+
+import java.security.AccessController;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+
+import javax.security.auth.Subject;
+
+import org.jboss.security.SecurityContext;
+import org.jboss.security.SecurityContextFactory;
+import org.jboss.security.plugins.SecurityContextAssociation;
+
+
+/** A collection of privileged actions for this package
+* @author Scott.Stark at jboss.org
+* @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+* @author <a her="mailto:tim.fox at jboss.com">Tim Fox</a>
+* @version $Revison: 1.0$
+*/
+class SecurityActions
+{
+ interface PrincipalInfoAction
+ {
+ PrincipalInfoAction PRIVILEGED = new PrincipalInfoAction()
+ {
+ public void push(final Principal principal, final Object credential,
+ final Subject subject, final String domain)
+ {
+ AccessController.doPrivileged(
+ new PrivilegedAction<Object>()
+ {
+ public Object run()
+ {
+ try
+ {
+ SecurityContext sc = SecurityContextFactory.createSecurityContext(domain);
+ SecurityContextAssociation.setSecurityContext(sc);
+ sc.getUtil().createSubjectInfo(principal, credential, subject);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ return null;
+ }
+ }
+ );
+ }
+ public void pop()
+ {
+ AccessController.doPrivileged(
+ new PrivilegedAction<Object>()
+ {
+ public Object run()
+ {
+ SecurityContextAssociation.clearSecurityContext();
+ return null;
+ }
+ }
+ );
+ }
+ };
+
+ PrincipalInfoAction NON_PRIVILEGED = new PrincipalInfoAction()
+ {
+ public void push(Principal principal, Object credential, Subject subject, String domain)
+ {
+ //ToDo: Get the correct security domain name
+ try
+ {
+ SecurityContext sc = SecurityContextFactory.createSecurityContext(domain);
+ SecurityContextAssociation.setSecurityContext(sc);
+ sc.getUtil().createSubjectInfo(principal, credential, subject);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void pop()
+ {
+ SecurityContextAssociation.clearSecurityContext();
+ }
+ };
+
+ void push(Principal principal, Object credential, Subject subject, String domain);
+ void pop();
+ }
+
+ static void pushSubjectContext(Principal principal, Object credential,
+ Subject subject, String domain)
+ {
+ if(System.getSecurityManager() == null)
+ {
+ PrincipalInfoAction.NON_PRIVILEGED.push(principal, credential, subject, domain);
+ }
+ else
+ {
+ PrincipalInfoAction.PRIVILEGED.push(principal, credential, subject, domain);
+ }
+ }
+ }
\ No newline at end of file
More information about the jboss-cvs-commits
mailing list