简体   繁体   中英

Encrypted messages using Apache Qpid

I'm trying to set up the encrypted messaging as shown in this guide/example

I have finished all of the steps up to the jndi properties. When I go to build the source code given at this site (with imports included), I get the following exception.

Source code:

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import javax.jms.BytesMessage;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class EncryptionExample {
    public EncryptionExample() {

    }

    public static void main(String[] args) throws Exception {
        EncryptionExample encryptionExampleApp = new EncryptionExample();
        encryptionExampleApp.runProducerExample();
        encryptionExampleApp.runReceiverExample();
    }

    private void runProducerExample() throws Exception {
        Connection connection = createConnection("producerConnectionFactory");

        try {
            Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
            Destination destination = createDesination("myTestQueue");

            MessageProducer messageProducer = session.createProducer(destination);
            TextMessage message = session.createTextMessage("Hello world!");

            // ============== Enable encryption for this message ==============
            message.setBooleanProperty("x-qpid-encrypt", true);
            // ============== Configure recipients for encryption ==============
            message.setStringProperty("x-qpid-encrypt-recipients", "CN=client1, OU=Qpid, O=Apache, C=US");

            messageProducer.send(message);
            session.commit();
        }
        finally {
            connection.close();
        }
    }

    private void runReceiverExample() throws Exception {
        Connection connection = createConnection("consumer1ConnectionFactory");

        try {
            connection.start();
            Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
            Destination destination = createDesination("myTestQueue");
            MessageConsumer messageConsumer = session.createConsumer(destination);
            Message message = messageConsumer.receive();

            if (message instanceof TextMessage) {
                // application logic
                System.out.println(((TextMessage) message).getText());
            } else if (message instanceof BytesMessage) {
                // handle potential decryption failure
                System.out.println("Potential decryption problem. Application not in list of intended recipients?");
            }

            session.commit();
        }
        finally {
            connection.close();
        }
    }

    ///////////////////////////////////////
    // The following is boilerplate code //
    ///////////////////////////////////////

    private Connection createConnection(final String connectionFactoryName) throws JMSException, IOException, NamingException {
        try (InputStream resourceAsStream = this.getClass().getResourceAsStream("example.properties")) {
            Properties properties = new Properties();
            properties.load(resourceAsStream);
            Context context = new InitialContext(properties);
            ConnectionFactory connectionFactory = (ConnectionFactory) context.lookup(connectionFactoryName);
            final Connection connection = connectionFactory.createConnection();
            context.close();
            return connection;
        }
    }

    private Destination createDesination(String desinationJndiName) throws IOException, NamingException {
        try (InputStream resourceAsStream = this.getClass().getResourceAsStream("example.properties")) {
            Properties properties = new Properties();
            properties.load(resourceAsStream);
            Context context = new InitialContext(properties);
            Destination destination = (Destination) context.lookup(desinationJndiName);
            context.close();
            return destination;
        }
    }
}

The error messages I am getting are the following:

Exception in thread "main" javax.naming.ConfigurationException: Failed
to parse entry: Virtual host found between indicies 7 and 12 
amqp://guest:guest@?brokerlist='tcp://localhost:5672?encryption_remote_trust_store='$certificates%255c/clientcerts''
       ^^^^^^^^^^^^ due to : Virtual host found at index 7: amqp://guest:guest@?brokerlist='tcp://localhost:5672?encryption_remote_trust_store='$certificates%255c/clientcerts''
[Root exception is Virtual host found between indicies 7 and 12 
amqp://guest:guest@?brokerlist='tcp://localhost:5672?encryption_remote_trust_store='$certificates%255c/clientcerts''
       ^^^^^^^^^^^^]    at org.apache.qpid.jndi.PropertiesFileInitialContextFactory.createFactory(PropertiesFileInitialContextFactory.java:247)
    at
org.apache.qpid.jndi.PropertiesFileInitialContextFactory.createConnectionFactories(PropertiesFileInitialContextFactory.java:160)
    at
org.apache.qpid.jndi.PropertiesFileInitialContextFactory.getInitialContext(PropertiesFileInitialContextFactory.java:118)
    at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
    at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)    at
javax.naming.InitialContext.init(Unknown Source)    at
javax.naming.InitialContext.<init>(Unknown Source)  at
EncryptionExample.createConnection(EncryptionExample.java:86)   at
EncryptionExample.runProducerExample(EncryptionExample.java:33)     at
EncryptionExample.main(EncryptionExample.java:27) Caused by: Virtual
host found between indicies 7 and 12 
amqp://guest:guest@?brokerlist='tcp://localhost:5672?encryption_remote_trust_store='$certificates%255c/clientcerts''
       ^^^^^^^^^^^^     at org.apache.qpid.url.URLHelper.parseError(URLHelper.java:143)     at
org.apache.qpid.client.url.URLParser.parseURL(URLParser.java:126)   at
org.apache.qpid.client.url.URLParser.<init>(URLParser.java:41)  at
org.apache.qpid.client.AMQConnectionURL.<init>(AMQConnectionURL.java:62)
    at
org.apache.qpid.client.AMQConnectionFactory.<init>(AMQConnectionFactory.java:83)
    at
org.apache.qpid.jndi.PropertiesFileInitialContextFactory.createFactory(PropertiesFileInitialContextFactory.java:241)
    ... 9 more

Since these errors mention line 86, which is:

Context context = new InitialContext(properties);

It seems to me that something is wrong with the properties file, which is currently the following(taken from the tutorial site, slightly modified):

java.naming.factory.initial = org.apache.qpid.jndi.PropertiesFileInitialContextFactory

# connection factories. This is where end-to-end encryption is configured on the client.
# connectionfactory.[jndiname] = [ConnectionURL]
connectionfactory.producerConnectionFactory = amqp://guest:guest@?brokerlist='tcp://localhost:5672?encryption_remote_trust_store='$certificates%255c/clientcerts''
connectionfactory.consumer1ConnectionFactory = amqp://<username>:<password>@?brokerlist='tcp://localhost:5672?encryption_key_store='path/to/client_1.jks'&encryption_key_store_password='<keystore_password>''
connectionfactory.consumer2ConnectionFactory = amqp://<username>:<password>@?brokerlist='tcp://localhost:5672?encryption_key_store='path/to/client_2.jks'&encryption_key_store_password='<keystore_password>''

# Rest of JNDI configuration. For example
# destination.[jniName] = [Address Format]
queue.myTestQueue = testQueue

So, I guess my real question is, how do I set up the properties file correctly so that I can run this example?

Apologies. There is a typo in the documentation. The connection url requires a / between the @ and the ? . This separates the clientid from the virtualhost name.

I have just updated the documentation within the source tree.

https://git-wip-us.apache.org/repos/asf?p=qpid-jms-amqp-0-x.git;h=56bacf6

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM