Azure Cosmos DB Spring Data RBAC with AAD Sample code.
This repo provides basic Spring Data sample code for Java SQL API to connect to Azure Cosmos DB using built-in role-based access control (RBAC), and authenticating using Azure Active Directory (AAD). See instructions below on setting up the RBAC/AAD requirements to access your Cosmos DB account and run the app successfully.
Java Development Kit 8
orJDK 11
if you run theazure-spring-data-cosmos-java-11-getting-started
.- An active Azure account. If you don't have one, you can sign up for a free account. Alternatively, you can use the Azure Cosmos DB Emulator for development and testing. As emulator https certificate is self signed, you need to import its certificate to java trusted cert store, explained here
- (Optional) SLF4J is a logging facade.
- (Optional) SLF4J binding is used to associate a specific logging framework with SLF4J.
- (Optional) Maven.
SLF4J is only needed if you plan to use logging, please also download an SLF4J binding which will link the SLF4J API with the logging implementation of your choice. See the SLF4J user manual for more information.
- git clone https://github.com/Azure-Samples/azure-spring-data-cosmos-java-sql-api-aad.git
- cd azure-spring-data-cosmos-java-sql-api-aad
-
Following the instructions here for creating an Azure AD application and service principal.
-
In the authentication section, be sure to select option 2 to create a new application secret, and make sure you store the secret value somewhere in a text editor.
-
Search for your app in Azure Portal --> Azure Active Directory --> App Registrations. You should see information like the below:
-
Review
resources/application.properties
in the repo you have cloned.- Replace
<Cosmos URI>
with the URI of your Cosmos DB account - Replace
<tenantId>
withDirectory (tenant) ID
from the portal. - Replace
<clientId>
withApplication (client) ID
from the portal - Replace
<clientSecret>
with the application secret value you created earlier - For the value of
cosmos.defaultScope
replace the<cosmos account>
part with the name of your Cosmos DB account (note this is used to test connection to AAD)
- Replace
Next we need to create a role that can access your Cosmos DB account appropriately. You should refer to the full instructions here for the various options. We'll just keep things simple here by creating a custom role using Azure CLI that has full permissions.
-
First, create a JSON file called
role-definition-rw.json
that contains the following:{ "RoleName": "MyReadWriteRole", "Type": "CustomRole", "AssignableScopes": ["/"], "Permissions": [{ "DataActions": [ "Microsoft.DocumentDB/databaseAccounts/readMetadata", "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*", "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*" ] }] }
-
Upload the JSON file to Azure CLI, then run the below to create the role, replacing
<myResourceGroup>
and<myCosmosAccount>
with the resource group name and Cosmos DB account name respectively:resourceGroupName='<myResourceGroup>' accountName='<myCosmosAccount>' az cosmosdb sql role definition create --account-name $accountName --resource-group $resourceGroupName --body @role-definition-rw.json
-
Now list the role definition you created to fetch it's ID:
az cosmosdb sql role definition list --account-name $accountName --resource-group $resourceGroupName
-
This should bring back a response like the below:
[ { "assignableScopes": [ "/subscriptions/<mySubscriptionId>/resourceGroups/<myResourceGroup>/providers/Microsoft.DocumentDB/databaseAccounts/<myCosmosAccount>" ], "id": "/subscriptions/<mySubscriptionId>/resourceGroups/<myResourceGroup>/providers/Microsoft.DocumentDB/databaseAccounts/<myCosmosAccount>/sqlRoleDefinitions/<roleDefinitionId>", "name": "<roleDefinitionId>", "permissions": [ { "dataActions": [ "Microsoft.DocumentDB/databaseAccounts/readMetadata", "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*", "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*" ], "notDataActions": [] } ], "resourceGroup": "<myResourceGroup>", "roleName": "MyReadWriteRole", "sqlRoleDefinitionGetResultsType": "CustomRole", "type": "Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions" } ]
-
Now go to Azure Portal --> Azure Active Directory --> Enterprise Applications and search for the application you created earlier. Record the
Object ID
found here. -
Now create a role assignment. Replace the
<aadPrincipalId>
withObject ID
you recorded above (note this is NOT the same as Object ID visible from the app registrations view you saw earlier). Also replace<myResourceGroup>
and<myCosmosAccount>
accordingly in the below. ReplaceroleDefinitionId>
with the value fetched from running the above command. Then run in Azure CLI:resourceGroupName='<myResourceGroup>' accountName='<myCosmosAccount>' readOnlyRoleDefinitionId = '<roleDefinitionId>' # as fetched above # For Service Principals make sure to use the Object ID as found in the Enterprise applications section of the Azure Active Directory portal blade. principalId = '<aadPrincipalId>' az cosmosdb sql role assignment create --account-name $accountName --resource-group $resourceGroupName --scope "/" --principal-id $principalId --role-definition-id $readOnlyRoleDefinitionId
-
Now that you have created an AAD application and service principle, created a custom role, and assigned that role permissions to your Cosmos DB account, you should be able to start your application.
-
run
mvn clean spring-boot:run
-
Note the following line of code in
SampleAppConfiguration.java
:checkAADSetup(servicePrincipal);
This will check access to your Cosmos DB account via AAD. If this check fails, there is an issue with AAD setup and/or connectivity to AAD. If setup is correct and there are no errors, in a production application you can remove this code.
Please refer to azure spring data cosmos for sql api source code for more information.