Struggling with optional claims in id/access token - azure-active-directory

I am updating an internally developed single-page app (Typescript/React) that uses OAuth2 from AD-FS 2016 to Azure AD v2. Things are complicated slightly by the fact that I (the developer) don't have direct access to the Azure console and am working on this with a (non-developer) sysadmin who does.
I have implemented PKCE and got the flow working; I can now obtain JWT access, ID and refresh tokens from the server and authenticate them via JWKS. So far so good.
Now, my apps to know a couple more things:
whether or not the user should be treated as an administrator. This is inferred from group memberships
the preferred username and first name/surname of the user
The first of these we dealt with by setting up a "role" and mapping it out to groups in the Azure console. We then added the role claim to the tokens. I can find this as a string array in "id_token". No problem.
I was confused for a while because I was looking for it in "access_token", but it's not a problem for my app to use "id_token" instead.
The second is the thing that is really giving us problems. No matter what we put into the "optional claims" dialog - we've added all these fields and more, for the ID token, they do not appear in it. Nothing we are doing seems to affect the actual tokens that come out at all.
I am beginning to think that I have missed something out with regards to obtaining the information. I am using the https://graph.microsoft.com/profile, https://graph.microsoft.com/email and https://graph.microsoft.com/user.read scopes and the administrator has authorized these on behalf of the app. The user is synced from our in-house active directory, which the AD-FS is running from as well, so I know that this information is in there. I tried messing with the resource parameter but this is deprecated in Azure AD v2 apparently.
I've read and re-read https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-optional-claims along with other online documentation, and the following passage confuses me and makes me think that the issue might be related to scopes:
Access tokens are always generated using the manifest of the resource, not the client. So in the request ...scope=https://graph.microsoft.com/user.read... the resource is the Microsoft Graph API. Thus, the access token is created using the Microsoft Graph API manifest, not the client's manifest. Changing the manifest for your application will never cause tokens for the Microsoft Graph API to look different. In order to validate that your accessToken changes are in effect, request a token for your application, not another app.
Or is that just the reason that I switched to using the id_token?
The optional_claims section of the configuration manifest looks like this:
"optionalClaims": {
"idToken": [
{
"name": "email",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "upn",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "groups",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "family_name",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "given_name",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "preferred_username",
"source": null,
"essential": false,
"additionalProperties": []
}
],
"accessToken": [
{
"name": "email",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "groups",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "preferred_username",
"source": null,
"essential": false,
"additionalProperties": []
}
],
"saml2Token": [
{
"name": "groups",
"source": null,
"essential": false,
"additionalProperties": []
}
]
},
But the resulting payload in the ID tag looks like this:
{
"aud": "redacted",
"iss": "https://login.microsoftonline.com/redacted/v2.0",
"iat": 1654770319,
"nbf": 1654770319,
"exp": 1654774219,
"email": "redacted",
"groups": [
"redacted",
"redacted",
"redacted",
"redacted"
],
"rh": "redacted",
"roles": [
"redacted"
],
"sub": "redacted",
"tid": "redacted",
"uti": "redacted",
"ver": "2.0"
}
Can anyone who has more experience of the platform help me understand what we are doing wrong here? Do we need to define custom scopes? Have we simply forgotten to turn an option on?
All help gratefully received! Thanks in advance...

I tried to reproduce the same in my environment and got below results:
I have implemented PKCE flow and got JWT access, ID and refresh tokens.
I added optional claims like below:
Go to Azure Portal -> Azure Active Directory -> App Registrations -> Your App -> Token Configuration
Please check the scopes you are using to get token.
When I gave only openid as scope, got response like below:
But when I gave scope as openid profile email user.read, got all optional claims successfully like below:

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

Blazor Authentication with Azure AD - Retrieving User Roles

I've successfully setup a Blazor application to authenticate with the Azure tenant where I work. The authentication works beautifully. I have the App Registration setup in Azure with appRoles defined in the manifest. I've add a few users to the application with those roles assigned however I'm not getting any Role claims back on the user context after it authenticates.
Startup.cs
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
});
Manifest:
"appRoles": [
{
"allowedMemberTypes": [
"User"
],
"description": "Coming soon.",
"displayName": "Viewer",
"id": "{guid goes here}",
"isEnabled": true,
"lang": null,
"origin": "Application",
"value": "Viewer"
},
{
"allowedMemberTypes": [
"User"
],
"description": "Coming soon.",
"displayName": "Manager",
"id": "{guid goes here}",
"isEnabled": true,
"lang": null,
"origin": "Application",
"value": "Manager"
}
],
I'm trying to retrieve those roles with the claims after authentication, but no roles are coming through. This is obviously making IsInRole not work and for the life of me I can't find any samples of code to achieve this.
I would greatly appreciate it if someone could point me in the right direction!
If the user has been assigned application roles, it should be returned in the id token. You can decode the id token by using https://jwt.io/.
I didn't find a blazor sample, but you can refer to this aspnetcore sample.

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 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