Grant admin consent - granted consent not taken into account - azure-active-directory

I have a JavaScript application, using MSAL.js 1.3.0. I'm prompted with the login screen and I'm able to login. But no matter how I configure the application in the Azure Portal, I'm always receiving thethe following message after I've logged in:
So, I granted the application admin consent: (which wasn't necessary for delegated permissions couple of weeks ago. Additionally, the page below doesn't show 'Admin consent required' at all)
But still, the behaviour doesn't change. I'm not able to get past the "need admin approval" message.
My coding is here:
config: {
msalConfig: {
auth: {
clientId: "b273e5a6-8940-481b-9c87-1b51310ff88c"
},
cache: {
cacheLocation: 'localStorage',
storeAuthStateInCookie: true
}
},
graphBaseEndpoint: "https://graph.microsoft.com/v1.0/",
userInfoSuffix: "me/",
queryMessagesSuffix: "me/messages?$search=\"$1\"&$top=150",
scopeConfig: {
scopes: ['User.Read', 'Mail.Read']
}
},
onInit: function () {
this.oMsalClient = new Msal.UserAgentApplication(this.config.msalConfig);
//check if the user is already signed in
if (!this.oMsalClient.getAccount()) {
this.oMsalClient.loginPopup(this.config.scopeConfig).then(this.fetchUserInfo.bind(this));
} else {
this.fetchUserInfo();
}
}
Here's my application manifest:
{
"id": "HERE-WOULD-BE-AN-ID",
"acceptMappedClaims": null,
"accessTokenAcceptedVersion": 2,
"addIns": [],
"allowPublicClient": null,
"appId": "b273e5a6-8940-481b-9c87-1b51310ff88c",
"appRoles": [],
"oauth2AllowUrlPathMatching": false,
"createdDateTime": "2020-06-09T10:31:12Z",
"groupMembershipClaims": null,
"identifierUris": [],
"informationalUrls": {
"termsOfService": null,
"support": null,
"privacy": null,
"marketing": null
},
"keyCredentials": [],
"knownClientApplications": [],
"logoUrl": null,
"logoutUrl": null,
"name": "2020-06-09 - Fiori Sandbox Test2",
"oauth2AllowIdTokenImplicitFlow": true,
"oauth2AllowImplicitFlow": true,
"oauth2Permissions": [],
"oauth2RequirePostResponse": false,
"optionalClaims": null,
"orgRestrictions": [],
"parentalControlSettings": {
"countriesBlockedForMinors": [],
"legalAgeGroupRule": "Allow"
},
"passwordCredentials": [],
"preAuthorizedApplications": [],
"publisherDomain": "d063937domain.onmicrosoft.com",
"replyUrlsWithType": [
{
"url": "https://d063937trial-d063937trialb-devspace-msgraph-ui.cfapps.eu10.hana.ondemand.com/ui/index.html",
"type": "Web"
}
],
"requiredResourceAccess": [
{
"resourceAppId": "00000003-0000-0000-c000-000000000000",
"resourceAccess": [
{
"id": "570282fd-fa5c-430d-a7fd-fc8dc98a9dca",
"type": "Scope"
},
{
"id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d",
"type": "Scope"
}
]
}
],
"samlMetadataUrl": null,
"signInUrl": null,
"signInAudience": "AzureADandPersonalMicrosoftAccount",
"tags": [],
"tokenEncryptionKeyId": null,
"verifiedPublisher": {
"displayName": null,
"verifiedPublisherId": null,
"addedDateTime": null
}
}
PS: I'm not a JavaScript developer, just took the recently working app from a colleague and wanted to use it. If anything is missing, please let me know.
Cheers,
Max

If you want end users can consent to apps accessing company data on their behalf, you need to log into Azure Portal by using an admin account to enable this feature.
Go to Azure Active Directory -> Enterprise applications -> User settings, select Yes for "Users can consent to apps accessing company data on their behalf".
If you want end users can request access to applications that require admin consent, you could configure the admin consent workflow.

I had a similar issue. It was because I did not have an MPN ID in my App Registration. (MPN => Microsoft Partner Network)
The result was that Users (even Admin) would be redirected automatically but concent just didnt work.

Related

Setup Microsoft Identify Platform and "Missing grant for this add-in" for localhost

I have an Excel add-in where single sign-on was implemented, but recently I realize that the SSO does not work anymore. So I tried to debug it in localhost.
First, I met the Missing grant for this add-in error in my add-in. Then, I had the same error with the sample project: https://learn.microsoft.com/en-us/office/dev/add-ins/quickstarts/sso-quickstart. Note that I don't have this error with https://learn.microsoft.com/en-us/office/dev/add-ins/develop/create-sso-office-add-ins-nodejs.
I created a test Azure account: test.sso.2023#gmail.com and registered the app. I put the updated code of sso-quickstart that produces the error in this repository.
After launching the code we could sign in Excel Online in Chrome, then sideload the add-in. Clicking on the button Get My User Profile Information launched Office.auth.getAccessToken, which raised the error POST https://login.microsoftonline.com/consumers/oauth2/v2.0/token 400 (Bad Request) and Missing grant for this add-in.
The request https://login.microsoftonline.com/consumers/oauth2/v2.0/token returned
AADSTS70000: The request was denied because one or more scopes requested are unauthorized or expired. The user must first sign in and grant the client application access to the requested scope...
The JSON of my settings on the Microsoft Identity Platform:
{
"id": "f61962fb-722b-465f-a265-4a1e70a744e3",
"acceptMappedClaims": null,
"accessTokenAcceptedVersion": 2,
"addIns": [],
"allowPublicClient": null,
"appId": "e55f4769-4293-4b71-94ea-5eb16dcfe41d",
"appRoles": [],
"oauth2AllowUrlPathMatching": false,
"createdDateTime": "2023-01-31T19:16:20Z",
"description": null,
"certification": null,
"disabledByMicrosoftStatus": null,
"groupMembershipClaims": null,
"identifierUris": [
"api://localhost:3000/e55f4769-4293-4b71-94ea-5eb16dcfe41d"
],
"informationalUrls": {
"termsOfService": null,
"support": null,
"privacy": null,
"marketing": null
},
"keyCredentials": [],
"knownClientApplications": [],
"logoUrl": null,
"logoutUrl": null,
"name": "sso",
"notes": null,
"oauth2AllowIdTokenImplicitFlow": false,
"oauth2AllowImplicitFlow": false,
"oauth2Permissions": [
{
"adminConsentDescription": "Allow Office to have read/write permissions to all user files and read permissions to all user mail. Office can call the app's web APIs as the current user.",
"adminConsentDisplayName": "Read/write permissions to user files. Read permissions to user mail and profiles.",
"id": "9b6c01b1-9818-4eb3-898c-e412fad8ae03",
"isEnabled": true,
"lang": null,
"origin": "Application",
"type": "User",
"userConsentDescription": "Allow Office to have read/write permissions to your files, and read permissions to your mail and profile.",
"userConsentDisplayName": "Read/write permissions to your files. Read permissions to your mail and profile.",
"value": "access_as_user"
}
],
"oauth2RequirePostResponse": false,
"optionalClaims": null,
"orgRestrictions": [],
"parentalControlSettings": {
"countriesBlockedForMinors": [],
"legalAgeGroupRule": "Allow"
},
"passwordCredentials": [
{
"customKeyIdentifier": null,
"endDate": "2023-07-30T18:17:18.762Z",
"keyId": "10c2239b-b83c-4085-b277-a37931990aa1",
"startDate": "2023-01-31T19:17:18.762Z",
"value": null,
"createdOn": "2023-01-31T19:17:25.3206496Z",
"hint": "~l2",
"displayName": "secret"
}
],
"preAuthorizedApplications": [
{
"appId": "ea5a67f6-b6f3-4338-b240-c655ddc3cc8e",
"permissionIds": [
"9b6c01b1-9818-4eb3-898c-e412fad8ae03"
]
},
{
"appId": "d3590ed6-52b3-4102-aeff-aad2292ab01c",
"permissionIds": [
"9b6c01b1-9818-4eb3-898c-e412fad8ae03"
]
},
{
"appId": "93d53678-613d-4013-afc1-62e9e444a0a5",
"permissionIds": [
"9b6c01b1-9818-4eb3-898c-e412fad8ae03"
]
}
],
"publisherDomain": null,
"replyUrlsWithType": [
{
"url": "https://localhost:3000/fallbackauthdialog.html",
"type": "Spa"
}
],
"requiredResourceAccess": [
{
"resourceAppId": "00000003-0000-0000-c000-000000000000",
"resourceAccess": [
{
"id": "14dad69e-099b-42c9-810b-d002981feec1",
"type": "Scope"
},
{
"id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d",
"type": "Scope"
},
{
"id": "37f7f235-527c-4136-accd-4a02d197296e",
"type": "Scope"
}
]
}
],
"samlMetadataUrl": null,
"signInUrl": null,
"signInAudience": "AzureADandPersonalMicrosoftAccount",
"tags": [],
"tokenEncryptionKeyId": null
}
And API permissions which can also be found in the above JSON:
Does anyone know what may be the cause of this error?
(* Link in Github office-js *)
I tried to reproduce the same in my environment and got below results:
I ran the below commands to create My Office Add-in for Excel using JavaScript and Single-sign-on by selecting required options:
npm install -g yo generator-office
yo office
Response:
Now I ran npm run configure-sso that took me to browser where I picked one user credentials:
Once the login is successful, I got output saying new application is registered successfully in Azure AD and updated source files automatically like below:
When I checked the same in Portal, Azure AD application is registered successfully with below details:
I have below API permissions added to the application automatically like below:
When I checked Expose an API tab, it added below details like App ID URI, scopes etc...
I have below Redirect URIs added to my application:
When I ran npm start command, it asked to install certificate initially like below:
This opened Excel with My Office Add-in where I got consent screen like below:
After consenting to the permissions, I got the user profile details successfully like below:
In your case, make sure to have one Azure account with active Azure subscriptions and assign Global administrator role to the test user account on that tenant, which is required to consent the permissions.
If you don't have active Azure accounts, get Free Trial subscription by clicking Start free button in this link.
Now, repeat the whole process by configuring the add-in again with this user credentials.
Redirect URIs: https://localhost:3000 (should it be https://localhost:3000 or https://localhost:8000?)
Of course. There is nothing running on localhost:3000. Everything should use the same URL.
Anyway, I'd suggest trying to create an empty add-in and use the automatic tool for registering the web add-in in Azure. Following that way you can be sure that SSO is working correctly for your tenant and the warning shown on the screenshot is not related to that if the sample add-in is working correctly. Then you can start delving deeper with your existing solution to find the root cause.
The configure-sso NPM package can help setting things up correctly for your sample add-in. See Single sign-on (SSO) quick start for a guide.

Blazor WASM AzureAD IdentityServer results in AADSTS90023: Public clients can't send a client secret

I'm trying to get IdentityServer 6 in Blazor WASM (an Asp.Net hosted solution) to get to work with a Microsoft id but am running into the error message "AADSTS90023: Public clients can't send a client secret". I feel like I've tried every configuration I can think off but hopefully I still missed something.
The IdentityServer configuration uses the 'SPA' profile which I believe is correct for my scenario:
"IdentityServer": {
"Clients": {
"Blazor.Client": {
"ClientId": "Blazor.Client",
"ClientName": "Blazor.Client",
"Profile": "SPA",
"RedirectUri": "https://localhost:15601",
"LogoutUri": "https://localhost:15601"
}
}
}
The configuration code follows the simplest example:
.AddMicrosoftAccount(options =>
{
options.ClientId = <clientId>;
options.ClientSecret = <secret>
})
Because these code snippets are basically the simplest way of doing this I'm assuming something is wrong with my AzureAD application registration but I can't figure out what. I've included the manifest:
{
"id": "<id>",
"acceptMappedClaims": null,
"accessTokenAcceptedVersion": 2,
"addIns": [],
"allowPublicClient": false,
"appId": "<apiId>",
"appRoles": [],
"oauth2AllowUrlPathMatching": false,
"createdDateTime": "2021-12-10T09:21:08Z",
"certification": null,
"disabledByMicrosoftStatus": null,
"groupMembershipClaims": null,
"identifierUris": [
"api://<apiId>"
],
"informationalUrls": {
"termsOfService": null,
"support": null,
"privacy": null,
"marketing": null
},
"keyCredentials": [],
"knownClientApplications": [],
"logoUrl": null,
"logoutUrl": null,
"name": "<name>",
"oauth2AllowIdTokenImplicitFlow": false,
"oauth2AllowImplicitFlow": false,
"oauth2Permissions": [],
"oauth2RequirePostResponse": false,
"optionalClaims": null,
"orgRestrictions": [],
"parentalControlSettings": {
"countriesBlockedForMinors": [],
"legalAgeGroupRule": "Allow"
},
"passwordCredentials": [
{
"customKeyIdentifier": null,
"endDate": "2023-12-10T09:21:45.315Z",
"keyId": "<keyId>",
"startDate": "2021-12-10T09:21:45.315Z",
"value": null,
"createdOn": "2021-12-10T09:21:57.2927675Z",
"hint": "H1f",
"displayName": "<displayName>"
}
],
"preAuthorizedApplications": [],
"publisherDomain": "<publisherDomain>.onmicrosoft.com",
"replyUrlsWithType": [
{
"url": "https://localhost:15602/signin-microsoft",
"type": "Spa"
}
],
"requiredResourceAccess": [
{
"resourceAppId": "00000003-0000-0000-c000-000000000000",
"resourceAccess": [
{
"id": "<someId>",
"type": "Scope"
}
]
}
],
"samlMetadataUrl": null,
"signInUrl": null,
"signInAudience": "AzureADandPersonalMicrosoftAccount",
"tags": [],
"tokenEncryptionKeyId": null
}
Is this scenario not supported or am I doing something wrong?
EDIT: ultimately the problem lied in the redirect uri platform which should not be set to 'SPA' but to 'Web' because it isn't the client doing the authentication but the IdentityServer web service. The relevant part would be:
"replyUrlsWithType": [
{
"url": "https://localhost:15602/signin-microsoft",
"type": "Web"
}
The
client secret actually must be kept secret, i.e; you cannot put it in the website
and use it from a public front-end .Client credentials flow design says the same.
Blazor webassembly applications are called a 'public
application' in oAuth/openid terms.
Note: According to microsoft docs:
Public clients (native applications and single page apps) must not use
secrets or certificates when redeeming an authorization code - always
ensure that your redirect URIs correctly indicate the type of
application
So try to disable the requirement for the client secret on the IdP and refresh tokens since they can't also be handled in a secure/safe way.
The recommendation is that you use code+PKCE for public clients,
which happens automatically when you set the response_type to code.
Reference: Microsoft identity platform and OAuth 2.0 authorization code flow - Microsoft identity platform | Microsoft Docs

AAD not providing refresh_token when requesting offline_access

For using Microsoft Graph in our application, I need a token for a specific user. I retrieve a bearer token form Azure Active Directory, but it is missing a refresh_token. It appears that the offline_access permission is being removed from the scopes.
The body of the request I'm sending to the /token endpoint is:
{
code=*somecode*,
client_id=*my clientid*,
client_secret=*my clientsecret*,
redirect_uri=http://localhost:8080/msgraph/callback,
scope=profile Calendars.Read User.ReadBasic.All email User.Read offline_access Calendars.Read.Shared openid,
grant_type=authorization_code
}
I do not use implicit grants. The endpoint I connect to is V2.
In the App registration, I have added all the permissions from the sent scope.
In the token response, all of the requested scopes are returned, except for offline_access. The refresh_token is left empty but I do not receive any errors.
The manifest from the MSGraph administration is
{
"id": "xxxx",
"acceptMappedClaims": null,
"accessTokenAcceptedVersion": 2,
"addIns": [],
"allowPublicClient": null,
"appId": "xxxxx",
"appRoles": [],
"oauth2AllowUrlPathMatching": false,
"createdDateTime": "2018-06-07T07:53:26Z",
"groupMembershipClaims": null,
"identifierUris": [],
"informationalUrls": {
"termsOfService": null,
"support": null,
"privacy": null,
"marketing": null
},
"keyCredentials": [],
"knownClientApplications": [],
"logoUrl": null,
"logoutUrl": null,
"name": "xxxxx",
"oauth2AllowIdTokenImplicitFlow": true,
"oauth2AllowImplicitFlow": true,
"oauth2Permissions": [],
"oauth2RequirePostResponse": false,
"optionalClaims": null,
"orgRestrictions": [],
"parentalControlSettings": {
"countriesBlockedForMinors": [],
"legalAgeGroupRule": "Allow"
},
"passwordCredentials": [
{
"customKeyIdentifier": null,
"endDate": "2099-12-31T12:00:00Z",
"keyId": "xxxxx",
"startDate": "2018-06-07T07:58:18.4289954Z",
"value": null,
"createdOn": "2018-06-07T07:58:21.1632167Z",
"hint": "gpi",
"displayName": null
}
],
"preAuthorizedApplications": [],
"publisherDomain": "xxxx.onmicrosoft.com",
"replyUrlsWithType": [
{
"url": "http://localhost:8080/msgraph/callback",
"type": "Web"
}
],
"requiredResourceAccess": [
{
"resourceAppId": "xxxxx",
"resourceAccess": [
{
"id": "64a6cdd6-aab1-4aaf-94b8-3cc8405e90d0",
"type": "Scope"
},
{
"id": "7427e0e9-2fba-42fe-b0c0-848c9e6a8182",
"type": "Scope"
},
{
"id": "37f7f235-527c-4136-accd-4a02d197296e",
"type": "Scope"
},
{
"id": "14dad69e-099b-42c9-810b-d002981feec1",
"type": "Scope"
},
{
"id": "465a38f9-76ea-45b9-9f34-9e8b0d4b0b42",
"type": "Scope"
},
{
"id": "2b9c4092-424d-4249-948d-b43879977640",
"type": "Scope"
},
{
"id": "570282fd-fa5c-430d-a7fd-fc8dc98a9dca",
"type": "Scope"
},
{
"id": "7b9103a5-4610-446b-9670-80643382c1fa",
"type": "Scope"
},
{
"id": "f45671fb-e0fe-4b4b-be20-3d3ce43f1bcb",
"type": "Scope"
},
{
"id": "88d21fd4-8e5a-4c32-b5e2-4a1c95f34f72",
"type": "Scope"
},
{
"id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d",
"type": "Scope"
},
{
"id": "b340eb25-3456-403f-be2f-af7a0d370277",
"type": "Scope"
}
]
}
],
"samlMetadataUrl": null,
"signInUrl": "http://localhost:8080/",
"signInAudience": "AzureADandPersonalMicrosoftAccount",
"tags": [
"guidedSetupCreatedOrUpdated",
"appModelVersion:2",
"accessTokenVersion:1",
"availableToOtherTenants:true",
"supportsConvergence:true"
],
"tokenEncryptionKeyId": null
}
The request body you posted above isn't in application/x-www-form-urlencoded. Since you're getting an access_token, I'm assuming this is just what you're providing to whichever library you're using to make the actual HTTP request. Just in case, the actual request body should look something like this (line breaks for readability):
grant_type=authorization_code&
code=[AUTHORIZATION CODE]&
client_id=[APPLICATION ID]&
client_secret=[PASSWORD]&
scope=[SCOPE]&
redirect_uri=[REDIRECT URI]
The values your sending looking correct to me with one exception, you shouldn't be passing prompt=consent at this stage.
The prompt parameter is used to force the user to consent during the interactive 1st phase of the flow, not when retrieving the token in the 2nd. It shouldn't result in the behavior you're experiencing but "shouldn't" and "doesn't" are often not the same thing.
If, however, you've added offline_access after the user has consented and you're only passing prompt=consent at this stage, it is possible your app has not received consent for offline_access yet. The token response will only provide scopes that have been consented.
If the user hasn't consented to one of the requested scopes, it will simply not provide that permission rather than returning an error. This allows your app to compare the scopes returned to the scopes requested and allow you to determine if you need to request a reconsent.
To understand why this is/how this works, imagine you request both User.Read.All and User.ReadBasic.All. Since User.Read.All requires Admin Consent, it is possible for a user to login to your app before administrative consent has been granted. In that case, your app may fall back to using User.ReadBasic.All as an alternative. The only difference to the user would be the data you show them would be limited (i.e. maybe your app wants to show displayName and birthday but can fall back to only displayName).
I have analyzed the response from Microsoft today and now it contains the refresh_token! It seems that the is some delay since it did'nt work thursday but works now on monday.
The returned scope in the response still doesn't contain offline_access but the refresh_token parameter is now deliverd.
Thanks for your contributions!

How to match AppRoleAssignments with applications in "Graph explorer API"

How to match https://graph.microsoft.com/beta/me/appRoleAssignments with https://graph.microsoft.com/beta/applications.
Which ID should be matched?
How to compare these two JSON code -
{
"id": "cLsrKP9FQU-3yUaE6gaYwgT2qe43q4pAqMb4Kr9Cdp4",
"creationTimestamp": "2019-04-08T06:17:53.349594Z",
"appRoleId": "00000000-0000-0000-0000-000000000000",
"principalDisplayName": "<User Name>",
"principalId": "282bbb70-45ff-4f41-b7c9-4684ea0698c2",
"principalType": "User",
"resourceDisplayName": "Postman",
"resourceId": "d24064b4-1ee0-4507-a220-6faab7ba3fe0"
},
With
{
"id": "b5bb2bb9-bb5e-426a-a107-d2212020f614",
"deletedDateTime": null,
"isFallbackPublicClient": false,
"appId": "c21feb4a-040e-4067-8c14-55b1e015fc17",
"applicationTemplateId": null,
"identifierUris": [
"https://<OrgName>.onmicrosoft.com/5d959b28-00fd-4f67-8d14-1a6276919b28"
],
"createdDateTime": "2019-02-27T07:33:40Z",
"displayName": "Postman",
"isDeviceOnlyAuthSupported": null,
"groupMembershipClaims": null,
"optionalClaims": null,
"orgRestrictions": [],
"publisherDomain": "<OrgName>.onmicrosoft.com",
"signInAudience": "AzureADMyOrg",
"tags": [],
"tokenEncryptionKeyId": null,
"api": {
"requestedAccessTokenVersion": null,
"acceptMappedClaims": null,
"knownClientApplications": [],
"oauth2PermissionScopes": [
{
"adminConsentDescription": "Allow the application to access Postman on behalf of the signed-in user.",
"adminConsentDisplayName": "Access Postman",
"id": "2e9e3ada-8570-4e8a-b02b-f0822f4fd63c",
"isEnabled": true,
"type": "User",
"userConsentDescription": "Allow the application to access Postman on your behalf.",
"userConsentDisplayName": "Access Postman",
"value": "user_impersonation"
}
],
"preAuthorizedApplications": []
},
I want to filter out the apps assigned to me from the master list of applications.
Which ID should be matched?
Edited-
I am getting 403 error while calling this API through Web-Part - https://graph.microsoft.com/beta/applications
private _getListApplications(param): Promise<any> {
return this.context.aadHttpClientFactory
.getClient('https://graph.microsoft.com')
.then((client: AadHttpClient) => {
return client
.get("https://graph.microsoft.com/beta/applications", AadHttpClient.configurations.v1);
}).
then((responseListAllApps: SPHttpClientResponse) => {
return responseListAllApps.json();
});
}
{
"error": {
"code": "Authorization_RequestDenied",
"message": "Insufficient privileges to complete the operation.",
"innerError": {
"request-id": "a0cae64d-ae22-47a3-a765-3abe2b1c34a1",
"date": "2019-04-08T09:23:25"
}
}
}
No, there is no ID matched directly, you could not do that via these two APIs. You need to use GET https://graph.microsoft.com/beta/servicePrincipals/xxxxxxxxx as a medium.
First, call GET https://graph.microsoft.com/beta/me/appRoleAssignments, copy the resourceId in the response, it is the object id of the target resource (service principal) for which the assignment was made. Then call GET https://graph.microsoft.com/beta/servicePrincipals/<resourceId>, the appId in the response is the application id of the AD App. Then call GET https://graph.microsoft.com/beta/applications, the appId in the response is the same with the appId retuned by GET https://graph.microsoft.com/beta/servicePrincipals/<resourceId>. Then you can match them.
For more details about the properties, see these three links:
https://learn.microsoft.com/en-us/graph/api/resources/approleassignment?view=graph-rest-beta#properties
https://learn.microsoft.com/en-us/graph/api/resources/serviceprincipal?view=graph-rest-beta#properties
https://learn.microsoft.com/en-us/graph/api/resources/application?view=graph-rest-beta#properties

How to identify Azure AD cloud-based applications returned by Microsoft Graph API /beta/applications endpoint?

I have a work account in Azure AD which has been granted with access for some cloud based applications within an organisation. I can login, see and start the applications from the MyApps portal.
I created a simple Javascript (React) application that needs to read the same list of applications. I'm fetching it from Microsoft Graph API /beta/applications endpoint.
How do I filter the list to keep only the cloud based apps shown in MyApps portal?
I successfully implemented the following:
Authentication using MSAL against Azure AD.
Fetched the list of all applications within user's organisation from Microsoft Graph API (GET https://graph.microsoft.com/beta/applications). I can see the same list in Azure Portal (Azure Active Directory -> App registrations (Preview)) for the specified organisation which is named here "directory".
This is an application item returned by Microsoft Graph API and shown in MyApps portal:
{
"id": "xxxxxxxx-xxxx-xxxx-xxxx-28a2179502fc",
"deletedDateTime": null,
"isFallbackPublicClient": false,
"appId": "xxxxxxxx-xxxx-xxxx-xxxx-987d1f301c21",
"identifierUris": [ "https://bitbucket.xxxxxxxxxx.io/plugins/servlet/samlsso", "http://samlssoforbitbucketbyresolutionXXXXXXXXXXXXXXXXXB9CCD803EA52CD5", "http://instanceid_xxxxxxxx-xxxx-xxxx-xxxx-19ba3d89b76f_XXXXXXXXXXXXX342A36A84E328233FB4", "http://samlssoforbitbucketbyresolution/xxxxxxxx-xxxx-xxxx-xxxx-e3b08c22b8e9" ],
"createdDateTime": "2017-12-02T09:05:35Z",
"displayName": "Bitbucket",
"isDeviceOnlyAuthSupported": null,
"groupMembershipClaims": "SecurityGroup",
"optionalClaims": null,
"orgRestrictions": [],
"publisherDomain": null,
"signInAudience": "AzureADMyOrg",
"tags": [],
"tokenEncryptionKeyId": null,
"api": {
"requestedAccessTokenVersion": null,
"acceptMappedClaims": null,
"knownClientApplications": [],
"oauth2PermissionScopes": [
{
"adminConsentDescription": "Allow the application to access SAML SSO for Bitbucket by resolution GmbH on behalf of the signed-in user.",
"adminConsentDisplayName": "Access SAML SSO for Bitbucket by resolution GmbH",
"id": "xxxxxxxx-xxxx-xxxx-xxxx-f434ba7b017f",
"isEnabled": true,
"type": "User",
"userConsentDescription": "Allow the application to access SAML SSO for Bitbucket by resolution GmbH on your behalf.",
"userConsentDisplayName": "Access SAML SSO for Bitbucket by resolution GmbH",
"value": "user_impersonation"
}
],
"preAuthorizedApplications": []
},
"appRoles": [
{
"allowedMemberTypes": [ "User" ],
"description": "msiam_access",
"displayName": "msiam_access",
"id": "xxxxxxxx-xxxx-xxxx-xxxx-2c6355321d55",
"isEnabled": true,
"origin": "Application",
"value": null
}
],
"publicClient": { "redirectUris": [] },
"info": {
"termsOfServiceUrl": null,
"supportUrl": null,
"privacyStatementUrl": null,
"marketingUrl": null,
"logoUrl": "https://secure.aadcdn.microsoftonline-p.com/c1c6b6c8-ugrfrtjv0so5ofkk2h6reh-pajssvvffd-ccwghwns/appbranding/ovibbplm5xqvqcq-zht1z7zxk3gr-vyq3raaci-yoj4/1033/bannerlogo?ts=636727159738380290"
},
"keyCredentials": [],
"parentalControlSettings": {
"countriesBlockedForMinors": [],
"legalAgeGroupRule": "Allow"
},
"passwordCredentials": [],
"requiredResourceAccess": [],
"web": {
"redirectUris": [ "https://bitbucket.xxxxxxxxxx.io/plugins/servlet/samlsso", "https://*.lab.resolution.de/plugins/servlet/samlsso" ],
"homePageUrl": "https://*.lab.resolution.de/plugins/servlet/samlsso?metadata=samlssoforbitbucketbyresolution|ISV9.2|primary|z",
"logoutUrl": null,
"implicitGrantSettings": {
"enableIdTokenIssuance": true,
"enableAccessTokenIssuance": false
}
}
}
I would have been expected a flag or type field but I couldn't find any to differentiate the items.
This link is documenting MyApps portal.
And here is the documentation of the endpoint.
I will be grateful for any help to bring some light on this.

Resources