2013-10-03 132 views
1

我正在使用ActiveMQ 5.8.0,它支持AMQP 1.0作爲隊列代理。我試圖使用Qpid AMQP1.0客戶端jms庫從Java客戶端與此進行通信,但沒有看到指定密鑰庫和信任庫信息的方法。使用Qpid通過SSL與AMQP 1.0代理通信使用Qpid

我已通過Java VM選項(例如-Djavax.net.ssl.keyStore)傳遞SSL憑證來成功配置客戶端,但對於我的最終解決方案,這不是一個可接受的方法...我需要能夠從代碼中指定這些信息。

我目前使用createFromURL方法從URL中生成連接,該URL包含定義爲here的SSL參數,但密鑰庫信息(以及可能的故障轉移參數)似乎沒有從URL中解析。

String connectionUrl = "amqps://localhost/?brokerlist='tcp://localhost:5671?ssl='true'&key_store='C:/apache-activemq-5.8.0/conf/client.ks'&key_store_password='password'&trust_store='C:/apache-activemq-5.8.0/conf/client.ts'&trust_store_password='password'"; 
ConnectionFactoryImpl connectionFactory = ConnectionFactoryImpl.createFromURL(connectionUrl); 

有沒有人知道向連接提供安全信息的更好方法?

更新: 對,所以做了一些通過我已經確定了API挖掘該庫將使用默認的SSLSocketFactory

參見:org.apache.qpid.amqp_1_0.client.Connection

final Socket s; 
if(ssl) 
{ 
    s = SSLSocketFactory.getDefault().createSocket(address, port); 
} 

因此,似乎沒有辦法在JVM選項之外指定此信息來設置默認值......至少在當前版本的Qpid客戶端庫中。

回答

0

URL是放置SSL參數的正確位置嗎? ConnectionFactory應該不是javax.net.ssl.SSLContext然後創建連接? (我不熟悉ActiveMQ API的細節)

+0

感謝您的答覆。我相信ConnectionFactory負責設置隊列通信,所以我沒有直接控制它如何檢索SSLContext。如前所述,如果我通過JVM選項來配置SSLContext(即-D javax.net.ssl.trustStore = ...),那麼工廠使用密鑰庫信息,並且SSL握手工作正常。問題是我有多個SSL通信與不同的密鑰庫,所以我不能利用全局JVM選項。我需要一種爲這個特定連接傳遞SSL信息的方法 - 如果這是有道理的。 –

+0

我對RabbitMQ更加熟悉,但認爲這些API是相似的。他們的ConnectionFactory有一個方法useSslProtocol(javax.net.ssl。SSLContext上下文)。 SSLContext有一個init方法,我認爲它將傳遞給JVM的參數。從那裏我假設你可以爲每個連接創建一個SSLContext。 – Dan

+0

再次感謝,這似乎正是我正在尋找,但它似乎並不存在。 ActiveMQ AMQP頁面(http://activemq.apache.org/amqp.html)指向Java客戶端的apache Qpid,它似乎已經失去了這種功能。 –

3

QPID JMS AMQP 1.0客戶端的連接URL參數與以前的AMQP版本的參數稍有不同。

下面是,對於1.0客戶端工作的連接URL的一個示例:

amqp://myhost:myport?ssl=true&ssl-cert-alias=myalias&clientid=myclientid&remote-host=default&sync-publish=false&trust-store=C:/trusstore.ts&trust-store-password=mytrustkeypass&key-store=C:/keystore.ks&key-store-password=mykeypass 

this link

0

看到對於QPid,它支持AMQP版本1.0.0,0.9.0的版本的client configuration page at QPID也可以幫助您以編程方式執行此操作。

我還提供了一個成功的節目的示例代碼(注意:配置是我創建了一個類存儲所有的配置值):

String ampqProtocol = "amqp"; 
    List<String> queryVariables = new ArrayList<String>(); 

    if(config.isUseSSL()) { 
     queryVariables.add("transport.keyStoreLocation="+config.getKeyStorePath()); 
     queryVariables.add("transport.keyStorePassword="+config.getKeyStorePassword()); 
     queryVariables.add("transport.trustStoreLocation="+config.getTrustStorePath()); 
     queryVariables.add("transport.trustStorePassword="+config.getTrustStorePassword()); 
     queryVariables.add("transport.keyAlias="+config.getKeyStoreAlias()); 
     queryVariables.add("transport.contextProtocol="+config.getSslProtocol()); 
     queryVariables.add("transport.verifyHost="+!config.isDontValidateSSLHostname()); 
     ampqProtocol = "amqps"; 
    } 
    String connectionString = ampqProtocol+"://"+config.getAddress()+":"+config.getPort(); 
    if(!queryVariables.isEmpty()) { 
     try { 
      connectionString += "?"+URLEncoder.encode(StringUtils.join(queryVariables, "&"), StandardCharsets.UTF_8.name()); 
     } catch (UnsupportedEncodingException e) { 
      e.printStackTrace(); 
     } 
    } 

    Hashtable<Object, Object> env = new Hashtable<Object, Object>(); 
    env.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.qpid.jms.jndi.JmsInitialContextFactory"); 
    env.put("connectionfactory.myFactoryLookup", connectionString); 

    Context context = null; 
    ConnectionFactory connectionFactory = null; 
    try { 
     context = new InitialContext(env); 
     connectionFactory = (ConnectionFactory) context.lookup("myFactoryLookup"); 
    } catch (NamingException e) { 
     e.printStackTrace(); 
    } 

    Connection connection = null; 
    try { 
     connection = connectionFactory.createConnection(); 
     connection.start(); 
    } catch (JMSException e) { 
     e.printStackTrace(); 
    }