Open jayanth-quintet opened 3 months ago
I am looking into this
Any update on this?
Also, I was also trying to find the documentation about the permissions that need to be given for Intune MAM to work with mobile apps. I found dedicated Entra documentation about how to grant permission. However, what I am looking for is a documentation on what permissions are needed specifically for Intune MAM to work in mobile apps.
@jayanth-quintet , is this a multi-tenant application?
@kanishkaBagga Our app is a multi tenant application.
@jayanth-quintet - The error AADSTS650052 you’re encountering indicates that your application is trying to access a service that your organization doesn’t have a service principal for. This typically happens in multi-tenant applications when the required service principal hasn’t been created or consented to by the tenant admin. Here are some steps to resolve this issue:
@kanishkaBagga Thanks. Let me go through the above. I will get back to you.
@kanishkaBagga While I look into other points you mentioned in your comment, this is about the third point
Check API Permissions: Ensure that the API permissions required by your application are correctly configured in the Azure portal. Navigate to Azure Active Directory > App registrations > Your App > API permissions and verify that the necessary permissions are listed.
We assume the permissions are already provided. Reattaching the screenshot from the first message in this thread.
Do you think I need to grant any other permission for getting Intune MAM to work with Android application? I am still having difficulties finding a documentation that mentions about permissions in the context of getting Intune MAM to work.
Please find the link here - https://learn.microsoft.com/en-us/mem/intune/developer/app-sdk-get-started#give-your-app-access-to-the-intune-mobile-app-management-service ( It is already defined in your case ) Did you verify the above steps?
@kanishkaBagga Thanks for your reply.
_
KnownClientApplications: If your application is a multi-tier application, ensure that the knownClientApplications parameter is set in the app manifest. This parameter should include the client IDs of the applications that need to access the API. _
Our's is a single tier application.
_
Tenant-Specific Endpoint: : Instead of using the common endpoint, use the tenant-specific endpoint for authorization. This can sometimes resolve issues related to multi-tenant applications. _
During the development stage, we are working with a single tenant. In the auth_config.json file, we replaced tenant_id with the specific tenant_id.
{
"client_id" : "<our_client_id>",
"authorization_user_agent" : "DEFAULT",
"redirect_uri" : "msauth://<package_name>/<our_key_hash>",
"account_mode" : "SINGLE",
"authorities" : [
{
"type": "AAD",
"audience": {
"type": "AzureADandPersonalMicrosoftAccount",
"tenant_id": "<our_tenant_id>"
}
}
]
}
However, this didn't make any difference.
We assume, moving forward, we will need to move away from static config json file and dynamically configure the tenant details in code. But for now, we only have one tenant.
_
Admin Consent: Ensure that the tenant admin has granted consent for the application. You can do this by constructing an admin consent URL and having the admin navigate to it. The URL format is: _
Will get back to you on this. Just waiting for the admin consent to be done.
@kanishkaBagga Regarding your solution about granting admin consent
Admin Consent: Ensure that the tenant admin has granted consent for the application. You can do this by constructing an admin consent URL and having the admin navigate to it. The URL format is:
When the admin tried to do this, it took us to a screen where all the Permissions were listed with an Accept CTA button at the bottom (see screenshot). However, the Accept button is not doing anything when we click on it. It continued to load.
We used the developer option to see what is going on underneath and saw that the following error was displayed in the console.
Failed to launch 'msauth://code/msauth.
%3A%2F%2Fauth?admin_consent=True&tenant= ' because the scheme does not have a registered handler.
Any idea what is going on here? At least, we now know there is a permission there to be granted, but could you help out about this error?
@jayanth-quintet - Make sure that the application that is supposed to handle the msauth scheme is installed on your device. This is often the Microsoft Authenticator app or a similar application. Verify that the URL scheme is correctly registered in the application's manifest file. For Android, this would be in the AndroidManifest.xml file, and for iOS, it would be in the Info.plist file. Ensure that the tenant admin has granted consent for the application. You can do this by constructing an admin consent URL and having the admin navigate to it. The URL format is typically: https://login.microsoftonline.com/{tenant_id}/adminconsent?client_id={client_id}&state=12345&redirect_uri={redirect_uri} Replace {tenant_id}, {client_id}, and {redirect_uri} with the appropriate values for your application.
@kanishkaBagga
Make sure that the application that is supposed to handle the msauth scheme is installed on your device. This is often the Microsoft Authenticator app or a similar application.
I am pretty sure that the organization admin had tried to grant consent for the application from his desktop web browser. And he ran into the error we have mentioned in my previous comment.
As far as the mobile app is concerned, we always had the Intune company portal app installed on the mobile device we used to test our Intune integration.
Verify that the URL scheme is correctly registered in the application's manifest file. For Android, this would be in the AndroidManifest.xml file, and for iOS, it would be in the Info.plist file.
This is what we had in the Android manifest file for the Android app. We assume this is what you meant.
<activity android:name="com.microsoft.identity.client.BrowserTabActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="<our_app_package_name>"
android:path="/<keystore_keyhash>"
android:scheme="msauth" />
</intent-filter>
</activity>
Ensure that the tenant admin has granted consent for the application. You can do this by constructing an admin consent URL and having the admin navigate to it. The URL format is typically: https://login.microsoftonline.com/{tenant_id}/adminconsent?client_id={client_id}&state=12345&redirect_uri={redirect_uri} Replace {tenant_id}, {client_id}, and {redirect_uri} with the appropriate values for your application.
As we mentioned in our previous comment, the admin was unable to grant consent. The Accept button seems to do nothing. Do you have any idea about what was happening there.
is the URL looking like this - https://login.microsoftonline.com/
@kanishkaBagga
is the URL looking like this - https://login.microsoftonline.com/
/adminconsent?client_id= &redirect_uri=msauth. ://auth
For iOS, Yes.
For Android, it looked like below
https://login.microsoftonline.com/
@kanishkaBagga We have further updates on this. We have communicated with the support team in Microsoft Entra console and they have found out that the consent for all permissions we requested has been granted by the admin. They also asked us to add three API permissions for the app - offline-access, openid and profile. We have added them for the app in the Entra console.
After this, we tried to login via MSAL from the app. We have played around with the following scopes again.
val MSAL_SCOPES = arrayOf("https://graph.microsoft.com/User.Read", "https://msmamservice.api.application/DeviceManagementManagedApps.ReadWrite")
val parameters = SignInParameters.builder()
.withScopes(MSAL_SCOPES.toList())
.withActivity(activity)
.withCallback(authInteractiveCallback)
.build()
mMsalClientApplication?.signIn(parameters)
private val authInteractiveCallback = object: AuthenticationCallback {
override fun onSuccess(authenticationResult: IAuthenticationResult?) {
Log.e(MSAL_TAG, "onSuccess of authInteractiveCallback")
authenticationResult?.let { result ->
msalLog("account id ${result.account.id}")
msalLog("account authority ${result.account.authority}")
msalLog("account username ${result.account.username}")
msalLog("account idToken ${result.account.idToken}")
msalLog("account tenantId ${result.account.tenantId}")
msalLog("result tenantId ${result.tenantId}")
msalLog("result scope ${result.scope}")
msalLog("result expiresOn ${result.expiresOn}")
msalLog("result accessToken ${result.accessToken}")
msalLog("result authenticationScheme ${result.authenticationScheme}")
msalLog("result authorizationHeader ${result.authorizationHeader}")
msalLog("result correlationId ${result.correlationId}")
}
}
override fun onError(exception: MsalException?) {
msalLog("onError of authInteractiveCallback")
msalLog(exception?.localizedMessage ?: "excemption Null")
if (exception is MsalDeclinedScopeException) {
msalLog("Declined scopes : ${exception.declinedScopes?.toString() ?: ""}")
msalLog("Granted scopes : ${exception.grantedScopes?.toString() ?: ""}")
}
exception?.printStackTrace()
}
override fun onCancel() {
msalLog("onCancel of authInteractiveCallback")
}
}
When we used both the scopes when trying to login, the Microsoft login screen showed up, but after signing in, the onError callback got called with the exception of type MsalDeclinedScopeException
. When we tried to print the declined and granted scopes from this exception, we found that
Declined Scopes https://graph.microsoft.com/user.read
Granted Scope https://msmamservice.api.application/DeviceManagementManagedApps.ReadWrite
For some reason the user.read
graph API permission is getting declined when I include the DeviceManagementManagedApps.ReadWrite
permission.
val MSAL_SCOPES = arrayOf("https://graph.microsoft.com/User.Read")
When we removed the second permission and tried login again, the login was successful. We received the onSuccess authentication callback with the correct account details. However, when we tried to register for MAM using the Intune SDK using the registerAccountForMAM
call, we received a MAM_ENROLLMENT_RESULT
notification with NOT_LICENSED
error.
val mgr = MAMComponents.get(MAMEnrollmentManager::class.java)
mgr?.registerAccountForMAM(
account.username, //upn
account.id, //aadid
account.tenantId, //tenantID
account.authority //authority
)
//logsReceived MAMEnrollmentNotification: MAM_ENROLLMENT_RESULT
notif.enrollmentResult.name: NOT_LICENSED
notif.error?.name: NONE_KNOWN
notif.scenario?.name: ENROLLMENT
notif.enrollmentResult?.code: 1
Basically we are kind of confused. If we add the permission DeviceManagementManagedApps.ReadWrite
in the scope, that permission is getting accepted, but the graph API permission User.Read
getting declined. However, if we remove the DeviceManagementManagedApps.ReadWrite
permission, the graph API permission is getting accepted.
We have used the Send logs feature in Company Portal APP and the incident ID that is shown there is YTJDDR42. Does this help you to get the logs for this issue?
On a side note, do we really need the https://msmamservice.api.application/DeviceManagementManagedApps.ReadWrite
permission in the scope for registering and working with MAM? We are asking because the sample TaskR app coming with the SDK doesn't add this.
Let us know.
@jayanth-quintet yes this would help , I am checking the logs based on your incident id
@kanishkaBagga Just an update on this. I had a call with Intune configuration level support in Microsoft and they have confirmed that
Basically, we are getting the same error in the Intune sample app as well (we changed its package name and added some logs, no other changes were made)
Did you get any information from the logs we shared. Morever, we have sent todays logs as well. Incident ID 83X8KWB2
Let us know.
@kanishkaBagga Is there any way to contact Intune developer support directly? (not in a public forum like this so that we can share the configuration details)
@jayanth-quintet , In the acquire token method you need to return a token with the "https://msmamservice.application.app/DeviceManagementManagedApps.ReadWrite" scope.
Also Review Conditional Access Policies. Conditional Access policies can sometimes cause conflicts with permissions. You can review these policies in the Azure portal by navigating to Azure Active Directory > Security > Conditional Access. Here, you can see all the policies that are applied and check if any of them might be affecting the permissions you're trying to use.
You can try opening a ticket from Troubleshooting + Support blade on intune portal
@kanishkaBagga
In the acquire token method you need to return a token with the "https://msmamservice.application.app/DeviceManagementManagedApps.ReadWrite" scope.
We tried adding this scope
public static final String[] MSAL_SCOPES = {
"https://graph.microsoft.com/User.Read",
"https://msmamservice.application.app/DeviceManagementManagedApps.ReadWrite"
};
However, we get error
com.microsoft.identity.client.exception.MsalServiceException: AADSTS500011: The resource principal named https://msmamservice.application.app was not found in the tenant named {our_tenant_id}. 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. Trace ID: 33404ddb-3592-4500-9aff-e3865c843800 Correlation ID: c04ad4b3-6146-4fce-b119-09b22474ab7a Timestamp: 2024-10-23 05:43:52Z
We understood this as we have not specified this permission in Entra console Api Permission pane. However, we couldn't find this specific permisison at all. The only DeviceManagementManagedApps.ReadWrite
permission we could find was under Microsoft Mobile Application Management header, which we already added and admin consent granted (see the screenshot in our previous comment here )
Also Review Conditional Access Policies. Conditional Access policies can sometimes cause conflicts with permissions. You can review these policies in the Azure portal by navigating to Azure Active Directory > Security > Conditional Access. Here, you can see all the policies that are applied and check if any of them might be affecting the permissions you're trying to use.
Actually, in Azure Portal there are absolutely no policies specified. The "Conditional Access" option is disabled. See screenshot
Kind of confused on this. Did you mean Entra console? Our understanding was we should be doing the configuration in Entra console. Moreover, we are trying to do MAM and the policies we have created are in Intune console.
@jayanth-quintet - Also, what is the resource id in final String[] scopes = {resourceId + "/.default"};
public class AuthenticationCallback implements MAMServiceAuthenticationCallback { private static final Logger LOGGER = Logger.getLogger(AuthenticationCallback.class.getName());
private final Context mContext;
public AuthenticationCallback(@NonNull final Context context) {
this.mContext = context.getApplicationContext();
}
@Nullable
@Override
public String acquireToken(@NonNull final String upn, @NonNull final String aadId, @NonNull final String resourceId) {
try {
// Create the MSAL scopes by using the default scope of the passed in resource id.
final String[] scopes = {resourceId + "/.default"};
final IAuthenticationResult result = MSALUtil.acquireTokenSilentSync(mContext, aadId, scopes);
if (result != null)
return result.getAccessToken();
} catch (MsalException | InterruptedException e) {
LOGGER.log(Level.SEVERE, "Failed to get token for MAM Service", e);
return null;
}
@kanishkaBagga The resourceId printed as "https://msmamservice.api.application"
So the full scope send to acquireTokenSilentSync
method as per the code below
final String[] scopes = {resourceId + "/.default"};
is https://msmamservice.api.application/.default
Basically, we kept it as is from the TaskR sample app. Today, we also played around with it and hardcoded the scopes below and send them to acquireTokenSilentSync method.
public static final String[] MSAL_SCOPES = {
"https://graph.microsoft.com/User.Read",
"https://msmamservice.application.app/DeviceManagementManagedApps.ReadWrite"
}
However, that also resulted in NOT_LICENSED error.
@kanishkaBagga As I mentioned above, I have two test users, both have Intune license. I have created a Group that contains only these two users. And in the Intune console for my app, I have assigned my app to this group only.
I just read that it is possible to assign Intune license to both users and groups. We have only assigned license to the individual users only, not to the group. Does this cause the NOT_LICENSED error that we are currently getting?
@jayanth-quintet - how are you passing the scopes in the acquire token call ?
final String[] scopes = {resourceId + "/.default"}; , here you need to pass only resourceid which is "https://msmamservice.api.application/" , in the token that you are acquiring for MS Graph , you can send only the user.read scope.
@kanishkaBagga Not sure I understand your point. This is the acquireToken method from my app. You can see two commented lines. I tried all three ways in the code shown below, one after another. None of them worked.
Could you clarify how I should change this?
public String acquireToken(@NonNull final String upn, @NonNull final String aadId, @NonNull final String resourceId) {
try {
// Create the MSAL scopes by using the default scope of the passed in resource id.
final String[] scopes = {resourceId + "/.default"};
// final String[] scopes = {resourceId + "/DeviceManagementManagedApps.ReadWrite"};
// final String[] scopes = {"User.Read", resourceId + "/DeviceManagementManagedApps.ReadWrite"};
final IAuthenticationResult result = MSALUtil.acquireTokenSilentSync(mContext, aadId, scopes);
if (result != null)
return result.getAccessToken();
} catch (MsalException | InterruptedException e) {
LOGGER.log(Level.SEVERE, "Failed to get token for MAM Service", e);
return null;
}
return null;
}
Moreover, when I call acquireToken method of the MSALUtil class (taken as is from the TaskR sample APP) I tried with different combination of scopes as well.
public static final String[] MSAL_SCOPES = {"https://msmamservice.api.application/DeviceManagementManagedApps.ReadWrite"};
// public static final String[] MSAL_SCOPES = {"https://graph.microsoft.com/User.Read"};
// public static final String[] MSAL_SCOPES = {"https://graph.microsoft.com/User.Read", "https://msmamservice.api.application/DeviceManagementManagedApps.ReadWrite"};
// public static final String[] MSAL_SCOPES = {"https://graph.microsoft.com/User.Read", "https://msmamservice.application.app/DeviceManagementManagedApps.ReadWrite"};
MSALUtil.acquireToken(MainActivity.this, MSAL_SCOPES, loginHint, new AuthCallback());
Again, none of them worked.
@kanishkaBagga Just to add to my previous points about the group, our test devices are NOT enrolled in Intune console, because we are trying for MAM without device enrollment.
We only have a user group with two intune licensed users, though the group itself is not licensed. We have assigned the group to our app like below.
Let me know if there is something wrong with this setup.
@jayanth-quintet - is it possible for you to open a ticket with intune team to look at the configuration at your end. You can try opening it from Troubleshooting + Support blade on intune portal
Will do @kanishkaBagga. I already checked that option, but the only support option I found seemed to be third party service. Hence hesitated.
Just a question. The app is created in Entra console, where we give the Android package names, keyhash etc. We also request and consent for permission there.
In the Intune console, I created a store app, where there was no option to provide a package name. I then created a user group (named MobileTest as shown in the previous screenshot, both users in the group has license) and also added necessary policies.
I realised recently that there is no connection between the app created in Entra console and the app created in Intune console. Since the package name is not given in the Intune console, I wonder how the Intune SDK going to link the app in Intune with the same in Entra, where permission and authentications are done.
Hi @jayanth-quintet - The app is created in Entra console, where we give the Android package names, keyhash etc. We also request and consent for permission there. You pass these values in the auth_config.json.
Did you follow the below steps to add the app to Intune - https://learn.microsoft.com/en-us/mem/intune/apps/lob-apps-android#select-the-app-type
@kanishkaBagga
Did you follow the below steps to add the app to Intune - https://learn.microsoft.com/en-us/mem/intune/apps/lob-apps-android#select-the-app-type
These steps are for Line of Business (LOB) app, right? Ours is a store app. And when creating store apps in Intune console, there is no option to input the app package name and so on. There is no option to link to the related app created in Entra console.
Hi @jayanth-quintet - The app is created in Entra console, where we give the Android package names, keyhash etc. We also request and consent for permission there. You pass these values in the auth_config.json.
This is all done. It is just that there is no option in the Intune console to input a package name when we use the option to add a Store app there. I am not seeing any reference in the Intune console that tells me that it is somehow linked to the same app entry in Entra console. Even the app ID seems to be different.
@kanishkaBagga While we are trying to get through the Intune support, we have a couple of questions.
1) In the Tenant Administrator screen in the Intune console, I can see that the MDM Authority is shows an Unknown. As we mentioned, we are only trying for MAM, not MDM. We do not plan to enroll devices into the Intune console. In this case, do we need to have "Microsoft Intune" authority? Does we need it for MAM to work?
2) As mentioned, our test user is Intune licensed. However, when I click on the license details, I can see there are 8 licenses included and the user has all of them (see the screenshot below). However, in the images included in the documentation, they are mentioning total of 25 licenses under the umbrella of Intune. Since we are getting NOT_LICENSED error, wondering whether we are missing some license that preventing us from registering for MAM from the app.
MDM Authority Showing as Unknown: If you are only using MAM and not enrolling devices into the Intune console, you do not need to set the MDM authority to "Microsoft Intune". MAM can function independently without requiring MDM authority.
Licenses for MAM:Regarding the licenses, it seems there might be some confusion. The documentation you referred to mentions a total of 25 licenses under the Intune umbrella, but your test user only has 8 licenses. This discrepancy could be the reason for the NOT_LICENSED error. It's essential to ensure that all necessary licenses for MAM are included. You might want to verify the specific licenses required for MAM and compare them with the ones assigned to your test user. https://learn.microsoft.com/en-us/mem/intune/fundamentals/licenses-assign
Intune Android App SDK Policy Enforcement Issue
Questions to Ask Before Submission
Yes
Yes
MSAL SDK version 5.4.2 Intune SDK version 10.3.1
Summary
We are trying to integrate Microsoft Intune with our Android app to make it MAM aware. So far, we have integrated both MSAL and Intune SDK.
Integrated MSAL SDK with the app. When trying to login/acquire a token with MSAL, the app is requesting the following scopes.
val MSAL_SCOPES = arrayOf("https://graph.microsoft.com/User.Read", "https://msmamservice.api.application/DeviceManagementManagedApps.ReadWrite")
However, we are seeing that onError method of AuthenticationCallback is getting called with following error
We did some research and did not find a way to assign a Service Principal for MAM anywhere in both the Entra or Intune admin console. Such a step was not mentioned in Intune documentation as well. Any idea why this error is returning?
On a side note, in the sample app bundled with the Intune SDK, the second scope is not requested. So, we tried the same by removing the second scope from the MSAL_SCOPES array above and then tried to login/acquire token. This time, we received the MSAL token. However, when we tried to register for MAM, we received a different error.
val MSAL_SCOPES = arrayOf("https://graph.microsoft.com/User.Read")
Other Details:
Let me know if any other info is needed. I have attached some screenshots as well.
Any help is appreciated.