How Oauth can be used with Apache Qpid JMS 2.0 AMQP
Hi All,
I am using Apache Qpid JMS 2.0 to connect standalone PS+ broker on 5671 port. I am able to achieve using username and password however I am not able to authenticate using Oauth.
Our other clients written in nodejs are able to authenticate and connect on 5671 with AMQP protocol and Oauth.
As per doc
I am providing the url and username and password as below
String solaceHost = "amqps://<host>:5671?amqp.saslMechanisms=XOAUTH2";
String solaceUsername = Username
String solacePassword = access_token
However, I do not have any luck here :(
Can someone please guide me here
Answers
-
Hi @prashantk2000,
Were you able to figure out the issue? What you're doing makes sense to me but I haven't tried it out myself.
0 -
Hi Marc,
We tried but we couldn't make it. :(
0 -
Hi @prashantk2000. If this is still not resolved, can I ask a few questions? Your NodeJS apps: which API are they using? What exception does your JMS client see from the Solace broker? I'm assuming you've set the password to the actual access token? Not the string "access_token"..?? haha
There may be additional details that you can see in the error response from the Solace broker if you can snoop the wireline traffic. Have you ever used WireShark? It can decode AMQP. It might be able to show some additional broker error message in the response/exception you get.
0 -
Hello @prashantk2000 ,
the following Code works for me and I just tested it again. It is with some debugging/experimental statements, but it should make clear how it works:
package com.solace.oauth.demos; import org.apache.qpid.jms.JmsContext; import org.apache.qpid.jms.JmsTopic; import com.solace.oauth.azuread.AccessData; import com.solace.oauth.azuread.TokenClientDemonet; import org.apache.qpid.jms.JmsConnectionFactory; import org.json.JSONObject; import java.time.LocalDateTime; import java.util.Base64; /** * Subscribes to messages published to a topic using Apache Qpid JMS 2.0 API over AMQP 1.0 Solace Message Router is used as the * message broker. * This is the Subscriber in the Publish/Subscribe messaging pattern. */ public class AMQPTopicSubscriberOAUTH { //Use a Topic where you have access to (check the ACL of the Authorization Group) final String TOPIC_NAME = "app1/oauth"; private void run() throws Exception { //completely independent logic to retrieve the Access Token //here we get the complete response from the ID Provider and need to process it String idpResponse = TokenClientDemonet.retrieveAzureToken(); //Get the AccessToken from the IDP Response, this is depending on what your Token Client does JSONObject obj = new JSONObject(idpResponse); String AccessToken = obj.getString("access_token"); System.out.println("The Access Token is: "+AccessToken); //just to print the Token as JSON String[] allTokens = AccessToken.split("\\."); byte[] decodedBytes = Base64.getDecoder().decode(allTokens[1]); String decodedToken = new String(decodedBytes); System.out.println("Decoded Token is: "+decodedToken); // AMQP_HOST_URL is something like amqps://mr-connection-xyzabc4711g.messaging.solace.cloud:5671 String solaceHost = AccessData.AMQP_HOST_URL +"?amqp.saslMechanisms=XOAUTH2"; String username = AccessData.VPN_USER_NAME; System.out.println("Timestamp: "+ LocalDateTime.now()); String solacePassword = AccessToken; System.out.printf("AMQPTopicSubscriber is connecting to Solace router %s...%n", solaceHost); // Programmatically create the connection factory using default settings JmsConnectionFactory connectionFactory = new JmsConnectionFactory(username, solacePassword, solaceHost); // Establish connection that uses the Solace Message Router as a message broker try (JmsContext context = (JmsContext) connectionFactory.createContext()) { System.out.printf("Connected to the Solace router with client username '%s'.%n", username); // Create the publishing topic programmatically JmsTopic topic = (JmsTopic) context.createTopic(TOPIC_NAME); System.out.println("Awaiting message for Topic "+TOPIC_NAME); // create consumer and wait for a message to arrive. // the current thread blocks at the next statement until a message arrives String message = context.createConsumer(topic).receiveBody(String.class); System.out.printf("Message received: '%s'%n", message); } } public static void main(String[] args) throws Exception { new AMQPTopicSubscriberOAUTH().run(); } }
2 -
-
Hi @cpjani ,
this 2 java classes are just my implementation of getting the token from Azure and storing the necessary usernames, hostnames, and so on (which is not a recommended way in production code).
You will have different ways and values anyway. BTW, I generated the TokenClient Java code from Postman, after it was successful to get a token with the Postman calls. See this screenshot:
If you are using KeyCloak, it might be even easier to get a token, did you read Pauls and Victors Blog on that topic?
If you like, I can clean up package my code examples, but it is not very elegant, just demo code...
1