Authenticating to Cosmos DB with adal4j

Category: azure multifactorauthentication

Question

Izor on Tue, 23 Jul 2019 15:28:25


Hi,

I am trying to authenticate a background service to Cosmos DB.  Our DB administrator does not want us to use master key, so I am attempting to use Service Principal.

The following code is demostrates what I did.  I get an error message:

onFailure: com.microsoft.aad.adal4j.AuthenticationException: {"error_description":"AADSTS500011: The resource principal named myname.documents.azure.com was not found in the tenant named ce49f3bb-xxxx-xxxx-xxxx-xxxxxxxxxxxx. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant.\r\nTrace ID: 3440ee70-8f61-42f2-8a0f-xxxxxxxxxxx\r\nCorrelation ID: c97ae37a-c0e2-4b3d-9859-xxxxxxxxxxx\r\nTimestamp: 2019-07-22 23:51:13Z","error":"invalid_resource"}Exception in thread "main" java.lang.NullPointerException
at org.stcu.TryAzureAd.App.main(App.java:39)

package org.TryAzureAd;


import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import com.microsoft.aad.adal4j.AuthenticationContext;
import com.microsoft.aad.adal4j.AuthenticationResult;
import com.microsoft.aad.adal4j.ClientCredential;
import com.microsoft.aad.adal4j.AuthenticationCallback;

public class App {
private static final String ClientID = "xx";
private static final String ClientSecret = "*xx";
private static final String TenantID = "xx";
private static final String Authority = "https://login.microsoftonline.com/";
    private static final String Resource = "myname.documents.azure.com";

public static void main( String[] args ) throws Throwable
    {
        System.out.println( "Hello TryAzureAd" );

        ClientCredential credential = new ClientCredential(App.ClientID, App.ClientSecret);

        AuthenticationContext context = null;
        AuthenticationResult result = null;
        ExecutorService service = null;
        try {
            service = Executors.newFixedThreadPool(1);

            String refreshToken = null;
            MyAuthCallback myCallback = new MyAuthCallback();

            context = new AuthenticationContext(App.Authority + App.TenantID + "/", true, service);
            Future<AuthenticationResult> future = context
                    .acquireToken(App.Resource, credential, myCallback);
            result = future.get();
            System.out.printf("AuthResult: %s", result.toString());
        } catch (ExecutionException ex) {
throw ex.getCause();
        } finally {
service.isShutdown();
        }
    }
}

package org.TryAzureAd;

import com.microsoft.aad.adal4j.AuthenticationCallback;
import com.microsoft.aad.adal4j.AuthenticationResult;

public class MyAuthCallback implements AuthenticationCallback<AuthenticationResult> {

public void onFailure(Throwable arg0) {
System.err.printf("onFailure: %s", arg0.toString());
}

public void onSuccess(AuthenticationResult arg0) {
System.out.printf("access token: %s", arg0.getAccessToken());
}
}

Here is what I did on MSDN side:

I created a user id in "Azure Active Directory" under "App Registrations".  I then copied its Client ID and Tenant ID.  I went to Cosmos DB and gave that user read access to the database resource I referenced in resource variable "myname.documents.azure.com".

Under Authentication of "App Registrations" I enabled "Access tokens", NOT ID tokens.  I did NOT associate a redirect URI, because I am not trying to authenticate an end user.

Under "API Permissions" of "App Registration" section I tried to add a permission related to Cosmos DB, but I cannot locate one.  I also found that most of the available permissions are not enabled for "background" applications.  For example, "Azure Storage" has "Application permissions" disabled and "Delegated permissions" available with impersonation checkbox option.  Only "Microsoft Graph" seems to provide enabled "Application permissions".

Thank you

Replies

Frank Hu MSFT on Tue, 23 Jul 2019 23:33:05


Hello,

This error : AADSTS500011: The resource principal named myname.documents.azure.com was not found in the tenant named ce49f3bb-xxxx-xxxx-xxxx-xxxxxxxxxxxx. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant.\r\nTrace ID: 3440ee70-8f61-42f2-8a0f-xxxxxxxxxxx\r\nCorrelation ID: c97ae37a-c0e2-4b3d-9859-xxxxxxxxxxx\r\nTimestamp: 2019-07-22 23:51:13Z","error":"invalid_resource"}

Means that you Application with the App ID URI in the properties section of your AAD Application Registration does not have a respective service principal for the application registration object. 

I would suggest taking a look through this doc for further understanding on how the objects/service principals work : https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-how-applications-are-added

The issue here is that the resource doesn't exist. Currently you are not encountering a permissions related issue, although that might come later. 

For permission related issues I would suggest taking a further look through the permissions, as if you are using a service principal or a client credential flow you'll only be able to use application permissions. I would suggest taking a look at this doc for further information on the differences between delegated/application : https://docs.microsoft.com/en-us/azure/active-directory/develop/delegated-and-app-perms

Please remember to mark one of the responses as answer if your question has been answered. If not please let us know if there are anymore questions. Thanks