Generate Auth token – call Cosmos DB SQL REST APIs

 

Generate Authorization token – Cosmos DB REST APIs –  we have to generate it as per REST api call we are making.

More details about Cosmos DB – https://docs.microsoft.com/en-us/rest/api/cosmos-db/access-control-on-cosmosdb-resources

For POC we will create Authorization token for calling create document in Cosmos DB collection

To do this in MuleSoft application we have to add following repository and dependency in pom.xml

Dependency

<dependency>
	<groupId>com.microsoft.azure</groupId>
	<artifactId>azure-documentdb</artifactId>
	<version>2.1.2</version>
</dependency>

Repository

<repository>
	<id>mulesoft-azure-releases</id>
	<name>MuleSoft Releases Repository Azure</name>
	<url>https://mvnrepository.com/artifact/</url>
	<layout>default</layout>
</repository>

Updated pom.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.mycompany</groupId>
	<artifactId>cosmos-db-sample</artifactId>
	<version>1.0.0-SNAPSHOT</version>
	<packaging>mule-application</packaging>
	<name>cosmos-db-sample</name>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

		<app.runtime>4.2.2</app.runtime>
		<mule.maven.plugin.version>3.2.7</mule.maven.plugin.version>
	</properties>

	<build>
		<plugins>
			<plugin>
				<groupId>org.mule.tools.maven</groupId>
				<artifactId>mule-maven-plugin</artifactId>
				<version>${mule.maven.plugin.version}</version>
				<extensions>true</extensions>
				<configuration>
				<classifier>mule-application</classifier>
				</configuration>
			</plugin>
		</plugins>
	</build>

	<dependencies>
		<dependency>
			<groupId>org.mule.connectors</groupId>
			<artifactId>mule-http-connector</artifactId>
			<version>1.2.1</version>
			<classifier>mule-plugin</classifier>
		</dependency>
		<dependency>
			<groupId>org.mule.connectors</groupId>
			<artifactId>mule-sockets-connector</artifactId>
			<version>1.1.1</version>
			<classifier>mule-plugin</classifier>
		</dependency>
		<dependency>
			<groupId>com.microsoft.azure</groupId>
			<artifactId>azure-documentdb</artifactId>
			<version>2.1.2</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.7.5</version>
		</dependency>
	</dependencies>

	<repositories>
		  <repository>
			<id>anypoint-exchange</id>
			<name>Anypoint Exchange</name>
			<url>https://maven.anypoint.mulesoft.com/api/v1/maven</url>
			<layout>default</layout>
		</repository>
		<repository>
			<id>mulesoft-releases</id>
			<name>MuleSoft Releases Repository</name>
			<url>https://repository.mulesoft.org/releases/</url>
			<layout>default</layout>
		</repository>
		<repository>
			<id>mulesoft-azure-releases</id>
			<name>MuleSoft Releases Repository Azure</name>
			<url>https://mvnrepository.com/artifact/</url>
			<layout>default</layout>
		</repository>
	</repositories>
	<pluginRepositories>
		<pluginRepository>
			<id>mulesoft-releases</id>
			<name>mulesoft release repository</name>
			<layout>default</layout>
			<url>https://repository.mulesoft.org/releases/</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</pluginRepository>
	</pluginRepositories>

</project>

This will add the required dependency jar in our mule application

Now create GenerateCosmosDBAuthToken Class in mule application

Java code

package cosmosdb;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;

public class GenerateCosmosDBAuthToken {

	public static String generate(String verb, String resourceType, String resourceId, String key, String keyType, String tokenVersion, String date)
	{
		 String authorization = null;
		 System.out.println(date);
		 String payload=verb.toLowerCase()+"\n"
		 +resourceType.toLowerCase()+"\n"
		 +resourceId+"\n"
		 +date.toLowerCase()+"\n"
		 +""+"\n";
		 Mac sha256_HMAC;
		try {
			sha256_HMAC = Mac.getInstance("HmacSHA256");
		
		 SecretKeySpec secret_key = new SecretKeySpec(Base64.getDecoder().decode(key), "HmacSHA256");
		 sha256_HMAC.init(secret_key);
		 String signature = Base64.getEncoder().encodeToString(sha256_HMAC.doFinal(payload.getBytes("UTF-8")));
		 authorization=URLEncoder.encode("type="+keyType+"&ver="+tokenVersion+"&sig="+signature, "utf-8");
		 System.out.println(authorization);
		}catch (InvalidKeyException e) {
			e.printStackTrace();
		} 
		catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (IllegalStateException e) {
			e.printStackTrace();
		} 
		catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return authorization;
	}
	
	public static String getServerTime() {
		Calendar calendar = Calendar.getInstance();
		SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
		dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
		return dateFormat.format(calendar.getTime());
	}
}

Here we have two static methods

getServerTime – this will provide the server time in our desired format

generate – This will return the required Auth token

arguments in generate method:

    • Verb – REST API method e.g. POST, GET, PUT
    • resourceType – type of resource that the request is for, Eg. “dbs”, “colls”, “docs”.
    • resourceId – ResourceLink must maintain its case for the ID of the resource. Example, for a collection it looks like: “dbs/MyDatabase/colls/MyCollection”
    • key – PRIMARY KEY from keys section in Azure Cosmos DB details – please see this for more details
    • keyType – master as we are using primary key
    • tokenVersion – 1.0 default
    • date – the date we generated using getServerTime method call

More details about the argument – https://docs.microsoft.com/en-us/rest/api/cosmos-db/access-control-on-cosmosdb-resources#constructkeytoken

Now to generate Auth token through Dataweave

Dataweave

%dw 2.0
import java!cosmosdb::GenerateCosmosDBAuthToken
output application/java
var verb = "POST"
var resourceType = "docs" 
var resourceId = "dbs/hr/colls/employee"
var key = "0SZd1Zs3hySH915hKBTQCbewWnzIEI4S2YK8yHDaRwMrnzrZSwaa0hHy8IW21x4qbsQoswWIh3FW8TOd0fpSYw=="
var keyType = "master"
var tokenVersion = "1.0"
var serverDateTime = GenerateCosmosDBAuthToken::getServerTime() as String
---
{
	serverDateTime: serverDateTime,
	authKey: GenerateCosmosDBAuthToken::generate(verb, resourceType, resourceId, key, keyType, tokenVersion, serverDateTime)
}

This will generate both serverDateTime and authkey

Testing the application through SOAP UI

Generate Authorization token for Cosmos DB REST APIs

 

In Azure we can see the document

 

Sample application – cosmos-db-sample

Sample SOAP application – Cosmos-db-soapui-project

 

  
Thank you for taking out time to read the above post. Hope you found it useful. In case of any questions, feel free to comment below. Also, if you are keen on knowing about a specific topic, happy to explore your recommendations as well.
 
For any latest updates or posts on our website, you can follow us on LinkedIn. Look forward to connecting with you there.


Share this:
Subscribe
Notify of
guest
6 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Ryo
Ryo
3 years ago

Thanks so much for this! I was trying to put this together on my own but was missing the (payload.getBytes(“UTF-8”)) step. This implementation is clean and works perfectly.

bourbia
bourbia
3 years ago

Thanks a lot a lot a lot, love u

bharath veer
bharath veer
3 years ago

I am using this as stand-alone class but it is generating same token even if I change the date

Amit G
Amit G
2 years ago

I did try with above method and all steps are as it, but I do get below error
“code”:”BadRequest”,”message”:”Message: {\”Errors\”:[\”The collection cannot be accessed with this SDK version as it was created with newer SDK version.\”]}

Not sure from where this SDK version is getting used.

Amit G
Amit G
2 years ago

Not sure what is use of below dependency in this
<

dependency

>
    

<

groupId

>com.microsoft.azure</

groupId

>
    

<

artifactId

>azure-documentdb</

artifactId

>
    

<

version

>2.1.2</

version

>
</

dependency

>

I did created a mule application without this dependency as we are calling cosmos db rest api so no need of any dependency.