0
votes

I have 2 microsoft tenat AD tenant A and tenat B,

I need to call Azure APIs for Tenant B (like azure resource provisioning , read azure data, call cost APIs and some other azure APIs) via a app registered under Tenant A. I have implemented this via following way.

  1. Created a multitenant app under tenant A (only with graph API permissions).

  2. Getting azure refresh token via Authoriziation Code flow (Tenant B user(not a admin) gives consent to Tenant A app) using this URL

https://login.microsoftonline.com/common/oauth2/authorize?client_id=&response_mode=form_post&response_type=code&redirect_url=authscope=openid&state=297e2e0374a6cbfb0174a73dcfce0755&nonce=c6234c0c-ab14-49f4-aa41-827061841d61

  1. On successful redirection I received the refresh token.

  2. When I try to use that refresh token to get Access token for "https://management.azure.com" I am getting following error.

com.microsoft.aad.adal4j.AuthenticationException: {"error_description":"AADSTS65001: The user or administrator has not consented to use the application with ID '801e6372-f223-4acb-895c-c966a0ff57c6' named 'AnkitTestMFAApp'. Send an interactive authorization request for this user and resource.\r\nTrace ID: 0ec48b06-64cf-47ed-b5d7-8725fba91600\r\nCorrelation ID: 96d78b24-5442-469a-a798-0f1eace171c1\r\nTimestamp: 2020-09-20 12:41:09Z","error":"invalid_grant"} at com.microsoft.aad.adal4j.AdalTokenRequest.executeOAuthRequestAndProcessResponse(AdalTokenRequest.java:129) at com.microsoft.aad.adal4j.AuthenticationContext.acquireTokenCommon(AuthenticationContext.java:930) at com.microsoft.aad.adal4j.AcquireTokenCallable.execute(AcquireTokenCallable.java:70) at com.microsoft.aad.adal4j.AcquireTokenCallable.execute(AcquireTokenCallable.java:38) at com.microsoft.aad.adal4j.AdalCallable.call(AdalCallable.java:47) at java.util.concurrent.FutureTask.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) I am using com.microsoft.azure.credentials.AzureTokenCredentials class to acuire token.

Even when I am using any azure java sdk function

AzureTokenCredentials credentials = our Custom Implementation of AzureTokenCredentials Azure azure = Azure.authenticate(credentials).withSubscription(cloudAccount.getSubscriptionId());

Custom Implementation of AzureTokenCredentials

@Override public AuthenticationResult getAccessTokenByRefreshToken(String tenantId, String resource, String refreshToken, String clientId, String clientSecret) throws ExecutionException, InterruptedException, MalformedURLException { AuthenticationContext authContext; AuthenticationResult authResult; ExecutorService service = null; Future future;

    try {
        service = Executors.newFixedThreadPool(1);
        authContext = new AuthenticationContext(MessageFormat.format("{0}/{1}", "https://login.microsoftonline.com", tenantId), true,
                service);

        future = authContext.acquireTokenByRefreshToken(refreshToken, new ClientCredential(clientId, clientSecret),
                resource, null);

        authResult = future.get();

        return authResult;
    } finally {
        if (service != null) {
            service.shutdown();
        }
    }
}

I can see a service principle entry for this App under my Tenant B Enterprise Applications list.

What can be the possible issue? and how should be solve this?

Asking for admin approval

App Permissions

Consent user settings

Conditional Access details

Consent settings

Added Permissions As Low Risk section

1
If my answer is helpful for you, you can accept it as answer( click on the check mark beside the answer to toggle it from greyed out to filled in.). See meta.stackexchange.com/questions/5234/…. This can be beneficial to other community members. Thank you.Allen Wu

1 Answers

0
votes

This is because that Tenant B user(not a admin) doesn't consent the app for scope https://management.azure.com.

Here are the steps to fix it.

Delete the Enterprise Application in Tenant B, it will revoke the consent.

Add permission https://management.azure.com/user_impersonation in your Azure AD app in Tenant A.

enter image description here

Use the following string to get code and then refresh token. When you use Tenant B user to do the user consent, you will be required to consent for https://management.azure.com/user_impersonation permission.

https://login.microsoftonline.com/common/oauth2/authorize?client_id={your client id}&response_mode=query&response_type=code&redirect_url=https://localhost/&scope=openid https://management.azure.com/.default&state=297e2e0374a6cbfb0174a73dcfce0755&nonce=c6234c0c-ab14-49f4-aa41-827061841d61

This time the refresh token will take effect because you will find the https://management.azure.com/user_impersonation permission in your Tenant B Enterprise Application.

enter image description here