microsoftconnect / Taskr-Sample-Intune-Android-App

Taskr is a simple, open source, Android app designed to let you test out the capabilities of the Microsoft Intune APP SDK.
MIT License
21 stars 18 forks source link

Receiving AUTHORIZATION_NEEDED when doing app enrollment. #13

Closed wobo-swati closed 2 years ago

wobo-swati commented 3 years ago

Hi Team,

In our android app, I am unable to register the app for enrollment. Everything is set up according to sample which is provided but still i am receiving always "AUTHORIZATION_NEEDED" error code when i call registerAccountForMAM().

I am using MSAL with intune SDK and the app is registered as multi tenant. In AuthenticationCallback class : acquireToken(), i always get "AUTHORIZATION_NEEDED" notification status with below error

"com.microsoft.identity.client.exception.MsalUiRequiredException: AADSTS65001: The user or administrator has not consented to use the application with ID 'XXX' named 'XXX'. Send an interactive authorization request for this user and resource."

Error logs

 at com.microsoft.identity.client.PublicClientApplication$18.onError(PublicClientApplication.java:1894)
at com.microsoft.identity.common.internal.controllers.CommandDispatcher.commandCallbackOnError(CommandDispatcher.java:381)
at com.microsoft.identity.common.internal.controllers.CommandDispatcher.access$1100(CommandDispatcher.java:76)
at com.microsoft.identity.common.internal.controllers.CommandDispatcher$3.run(CommandDispatcher.java:363)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)

Code in Application class in onCreate()

 MAMEnrollmentManager mgr = MAMComponents.get(MAMEnrollmentManager.class);
        if (mgr != null) {
            mgr.registerAuthenticationCallback(new AuthenticationCallback(getApplicationContext()));
        }
        MAMComponents.get(MAMNotificationReceiverRegistry.class).registerReceiver(notification -> {
            if (notification instanceof MAMEnrollmentNotification) {
                MAMEnrollmentManager.Result result =
                        ((MAMEnrollmentNotification) notification).getEnrollmentResult();

                switch (result) {
                    case AUTHORIZATION_NEEDED:
                    case NOT_LICENSED:
                    case ENROLLMENT_SUCCEEDED:
                    case ENROLLMENT_FAILED:
                    case WRONG_USER:
                    case UNENROLLMENT_SUCCEEDED:
                    case UNENROLLMENT_FAILED:
                    case PENDING:
                    case COMPANY_PORTAL_REQUIRED:
                    default:
                        break;
                }
            } else {
            }
            return true;
        }, MAMNotificationType.MAM_ENROLLMENT_RESULT);

Login Code

PublicClientApplication.createMultipleAccountPublicClientApplication(this,
                R.raw.auth_config,
                new IPublicClientApplication.IMultipleAccountApplicationCreatedListener() {
                    @Override
                    public void onCreated(IMultipleAccountPublicClientApplication application) {
                        mMultipleAccountApp = application;
                        final String[] scope = {"user.read"};
                        if (mMultipleAccountApp != null) {
                            mMultipleAccountApp.acquireToken(MultipleAccountModeActivity.this, scope, getAuthInteractiveCallback());
                        }
                    }

                    @Override
                    public void onError(MsalException exception) {
                    }
                });  

Call back code

private com.microsoft.identity.client.AuthenticationCallback getAuthInteractiveCallback() {
        return new AuthenticationCallback() {

            @Override
            public void onSuccess(IAuthenticationResult authenticationResult) {
                IAccount account = authenticationResult.getAccount();
                final String upn = account.getUsername();
                final String aadId = account.getId();
                final String tenantId = account.getTenantId();
                final String authorityURL = account.getAuthority();

                MSUtil.setID(aadId);
                MSUtil.setAccessTokenD(authenticationResult.getAccessToken());

                // Register the account for MAM.
                mEnrollmentManager.registerAccountForMAM(upn, aadId, tenantId, authorityURL);
                final MAMEnrollmentManager.Result registeredAccountStatus = mEnrollmentManager.getRegisteredAccountStatus(upn);
            }

            @Override
            public void onError(MsalException exception) {
            }

            @Override
            public void onCancel() {
            }
        };
    }

Acqure token() in MAMServiceAuthenticationCallback

I have tried various things here, sending our app read token, getting a token based on the resource id, etc. In that case i seem to get NOT_LICENSED.

@Override
    public String acquireToken(@NonNull final String upn, @NonNull final String aadId, @NonNull final String resourceId) {
           final String[] scopes = {resourceId + "/.default"};
            final IAccount account = MSUtil.loadAccounts(MSUtil.getAaid());
            if (account == null) {
                try {
                    throw new MsalUiRequiredException(MsalUiRequiredException.NO_ACCOUNT_FOUND, "no account found for " + aadId);
                } catch (MsalUiRequiredException e) {
                    e.printStackTrace();
                }
            }

            AcquireTokenSilentParameters params =
                    new AcquireTokenSilentParameters.Builder()
                            .forAccount(account)
                            .fromAuthority(account.getAuthority())
                            .withScopes(Arrays.asList(scopes))
                            .build();
            final IAuthenticationResult iAuthenticationResult = mMultipleAccountApp.acquireTokenSilent(params);
            iAuthenticationResult.getAccessToken();   
 }

Config File

{
  "client_id": "906ae7fc-564d-4063-be19-533b2f7cc94c",
  "authorization_user_agent": "DEFAULT",
  "redirect_uri": "msauth://com.workboard.android.app/kbQSwM8PmRJ9K2Sh5lS4A3he9n8%3D",
  "account_mode" : "MULTIPLE",
  "broker_redirect_uri_registered": true,
  "multiple_clouds_supported": true,
  "authorities": [
    {
      "type": "AAD",
      "audience": {
        "type": "AzureADandPersonalMicrosoftAccount",
        "tenant_id": "common"
      }
    }
  ]
}

Here acquireTokenSilent() call is always falling for me with "MsalUiRequiredException: AADSTS65001" error and not able to get the access token.

I would expect to get ENROLLMENT_SUCCEEDED as a result instead of AUTHORIZATION_NEEDED.

bannus commented 2 years ago

@wobo-swati This repository contains the MAM sample app code. If you have not been able to resolve this issue, please post a new issue in ms-intune-app-sdk-android. Please be sure to include the version of the MAM SDK you are using, along with the other details in the issue template.