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
In Azure we can see the document
Sample application – cosmos-db-sample
Sample SOAP application – Cosmos-db-soapui-project
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.
Happy to help! Please share your finding if you see something new 🙂
Thanks a lot a lot a lot, love u
I am using this as stand-alone class but it is generating same token even if I change the date
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.
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.