代码之家  ›  专栏  ›  技术社区  ›  Carlos Campderrós

让activeMQ的用户拥有一个队列,该队列的名称就是用户的名称

  •  0
  • Carlos Campderrós  · 技术社区  · 12 年前

    在我的应用程序中,用户可以自由创建一个帐户,并且它需要拥有一个队列(或主题)来在它们之间通信2个后端进程。我不想修改 activemq 每次有人创建帐户时的配置。我已经创建了 jaasAuthenticationPlugin 而且效果很好。这是我的相关部分 activemq.xml 文件:

    <plugins>
      <!-- 'activemq-domain' defined in conf/login.conf -->
      <jaasAuthenticationPlugin configuration="activemq-domain" />
    
      <authorizationPlugin>
        <map>
          <authorizationMap>
            <authorizationEntries>
              <authorizationEntry queue="foobarQueue"
                  write="foobarGroup"
                  read="foobarGroup"
                  admin="foobarGroup"
              />
            </authorizationEntries>
          </authorizationMap>
        </map>
      </authorizationPlugin>
    </plugins>
    

    正如您可能推断的那样,身份验证插件正在对用户进行身份验证( foobar 在本例中),并将用户置于 foobarGroup 组这个 AuthorizationEntry 正在授予 read , write admin 对的权限 foobarQueue 到这个 foobar组 。这运行得很好,但现在如果我创建了一个新用户,我必须来到这个文件并添加一个新的 授权输入 。是否可以在 活动mq.xml 做一些类似的事情:

    <authorizationEntry
        queue="<% Username %>"
        write="<% Username %>"
        read="<% Username %>"
        admin="<% Username %>"
    />
    

    或者我应该写一些JAAS授权类来实现这一点吗?

    1 回复  |  直到 12 年前
        1
  •  3
  •   Carlos Campderrós    12 年前

    最后,我编写了一个类来处理授权部分。这有点困难,因为文档很难找到,而且我找不到任何好的例子。挖掘默认的源代码 LDAPAuthorizationMap 是关键。无论如何,任何感兴趣的人的消息来源:

    package com.example.activemq;
    
    
    import org.apache.activemq.advisory.AdvisorySupport;
    import org.apache.activemq.command.ActiveMQDestination;
    import org.apache.activemq.jaas.GroupPrincipal;
    import org.apache.activemq.security.AuthorizationMap;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    
    import java.util.HashSet;
    import java.util.Set;
    
    public class OwnedUserQueueAuthorizator implements AuthorizationMap {
        private static final Log log =
                LogFactory.getLog(OwnedUserQueueAuthorizator.class);
        private boolean debug = false;
    
        // the Destination will be the name of the user, and we should return that
        // the group with user name has read,write and admin privileges to the
        // topic/queue named like the username
    
    
        // for temporary destinations, if null is returned, then everybody has
        // permission.
    
        public Set<GroupPrincipal> getTempDestinationAdminACLs() {
            return null;
        }
    
        public Set<GroupPrincipal> getTempDestinationReadACLs() {
            return null;
        }
    
        public Set<GroupPrincipal> getTempDestinationWriteACLs() {
            return null;
        }
    
        // for persistent destinations
    
        public Set<GroupPrincipal> getAdminACLs(ActiveMQDestination destination) {
            if (debug) {
                log.debug("getAdminACLs: " + destination.getPhysicalName());
            }
            return getACLs(destination);
        }
    
        public Set<GroupPrincipal> getReadACLs(ActiveMQDestination destination) {
            if (debug) {
                log.debug("getReadACLs: " + destination.getPhysicalName());
            }
            return getACLs(destination);
        }
    
        public Set<GroupPrincipal> getWriteACLs(ActiveMQDestination destination) {
            if (debug) {
                log.debug("getwriteACLs: " + destination.getPhysicalName());
            }
            return getACLs(destination);
        }
    
        private Set<GroupPrincipal> getACLs(ActiveMQDestination destination) {
            Set<GroupPrincipal> result;
    
            if (AdvisorySupport.isAdvisoryTopic(destination)) {
                result = getACLsForAdvisory();
            } else {
                result = new HashSet<GroupPrincipal>();
                // Destination should be something like UUID or UUID.whatever...,
                // so we must add only the first component as the group principal
                result.add(new GroupPrincipal(
                        destination.getDestinationPaths()[0])
                );
            }
    
            if (debug) {
                String s = "";
                for (GroupPrincipal gp : result) {
                    s += ", " + gp.getName();
                }
                log.debug("groupPrincipals: " + "[" + s.substring(2) + "]");
            }
            return result;
        }
    
        private Set<GroupPrincipal> getACLsForAdvisory() {
            Set<GroupPrincipal> result = new HashSet<GroupPrincipal>();
            GroupPrincipal g = new GroupPrincipal("advisories");
            result.add(g);
            return result;
        }
    
        // Properties
        // -------------------------------------------------------------------------
    
        // if the <bean> definition in the activemq.xml has some
        // <property name="foo" value="..." />
        // defined, they will call this.setFoo($value), so, even if these get/set
        // methods aren't called from here, they are really needed.
    
        public void setDebug(String debug) {
            this.debug = "true".equalsIgnoreCase(debug);
        }
    
        public String getDebug() {
            return String.valueOf(debug);
        }
    }
    

    这个 conf/activemq.xml 文件:

    <beans ...>
        ...
        <broker ...>
        ...
            <plugins>                                                               
                <!-- 'activemq-domain' defined in conf/login.conf -->               
                <jaasAuthenticationPlugin configuration="activemq-domain" />        
    
                <authorizationPlugin>                                               
                    <map>                                                           
                        <bean id="OwnedUserQueueAuthorizationMap"                            
                            class="com.example.activemq.OwnedUserQueueAuthorizator"   
                            xmlns="http://www.springframework.org/schema/beans">    
                            <property name="debug" value="false"/>                   
                        </bean>                                                     
                    </map>                                                          
                </authorizationPlugin>                                              
            </plugins>   
            ...
        </broker>
        ...
    </beans>