Requirement:
We would like to query the groups of a user via Microsoft’s Graph API with the following request:
https://graph.microsoft.io/en-us/docs/api-reference/v1.0/api/user_getmembergroups
In our case the response looks like this:
{
"error": {
"code": "Authorization_RequestDenied",
"message": "Insufficient privileges to complete the operation.",
"innerError": {
"request-id": "a230a67e-8ef1-4f88-aa19-2c5b983c3de4",
"date": "2017-01-04T16:29:55"
}
}
}
(Note: the GET https://graph.microsoft.com/v1.0/me/ is working fine and returns the user data)
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity",
"id": "e23976a1-8bd9-4cca-a410-e095d2c2022d",
"businessPhones": [],
"displayName": "XXXX Vad",
"givenName": "XXXX",
"jobTitle": null,
"mail": null,
"mobilePhone": null,
"officeLocation": null,
"preferredLanguage": null,
"surname": "Vad",
"userPrincipalName": "XXXX.vad_outlook.com#EXT##XXXXvadoutlook.onmicrosoft.com"
}
Environment:
Application created on apps.dev.microsoft.com with the following parameters:
o Application Id: 412386c3-8fa3-4000-9039-748111407XXX
o Delegated Permissions: [ User.Read ]
This application is visible on ‘Azure Portal / AAD / Enterprise applications’ and the user with a group ‘BASIC’ is added to this application
An example of an access token obtained from AAD:
{
"aud": "https://graph.microsoft.com",
"iss": "https://sts.windows.net/b9df6a2d-9150-45f9-abf0-9c30f9e527c7/",
"iat": 1483548390,
"nbf": 1483548390,
"exp": 1483552290,
"acr": "1",
"aio": "AQABAAEAAADRNYRQ3dhRSrm-4K-adpCJhEVX2WEl4aboghl6AXaqOVcbaQPl1yYg1X1D2r4cNxBYmPvUiTKE9bB6wwpNSBKeD2OZXhrzdE3FPddCzbaTo84X8aSoKFaAt2vysYSv1HdChNXBPbfrVlA6YBuSwVwEIAA",
"altsecid": "1:live.com:00037FFEC5917401",
"amr": [
"pwd"
],
"app_displayname": "XXX test",
"appid": "412386c3-8fa3-4000-9039-748111407XXX",
"appidacr": "0",
"email": "XXXX.vad#outlook.com",
"family_name": "Vad",
"given_name": "XXXX",
"idp": "live.com",
"ipaddr": "165.225.80.95",
"name": "XXXX Vad",
"oid": "e23976a1-8bd9-4cca-a410-e095d2c20XXX",
"platf": "3",
"puid": "10037FFE9D51DXXX",
"scp": "User.Read",
"sub": "sCDfsIUynhm4GdgPIe8hYguyNbbc7IBjZeKLd1UDXXX",
"tid": "b9df6a2d-9150-45f9-abf0-9c30f9e52XXX",
"unique_name": "live.com#XXXX.vad#outlook.com",
"ver": "1.0"
}
What am I doing wrong or what’s missing? Any help is appreciated.
You have to have admin consent right now to pull groups. They changed the required permissions a while back.
https://blogs.msdn.microsoft.com/aadgraphteam/2015/03/18/update-to-graph-api-consent-permissions/
Related
I have a problem where I need the access token received from a custom policy B2C flow to contain certain claims, for example email. I have one flow for local login (email + password) and that gives me a correct access token, it contains email. However, my other flow for social IDP does not give an access token with any extra claims. An access token from Facebook looks something like this:
{
"typ": "JWT",
"alg": "RS256",
"kid": "IiippFxxxxxxxxxxxxxxxxxxqVEz16tNMOR0"
}.{
"iss": "https://xxxxxxxxxxxxxxx.b2clogin.com/a861612f-xxxxxxxxxxxxxxxx-34e14528d/v2.0/",
"exp": 1671466114,
"nbf": 1671462514,
"aud": "b0823952xxxxxxxxxxxxxxxx363b7bdfe0a",
"sub": "c1aceafd-xxxxxxxxxxxxxxxf4f1a0a83a7",
"idp": "facebook.com",
"tid": "a861612fxxxxxxxxxxxxxxxxxxxce534e14528d",
"nonce": "73eee291-xxxxxxxxxxxxxf6-85818e3efdab",
"scp": "user.read",
"azp": "b0823952-xxxxxxxxxxxxxxx2363b7bdfe0a",
"ver": "1.0",
"iat": 1671462514
}.[Signature]
While the access token from a local sign in looks like this:
{
"typ": "JWT",
"alg": "RS256",
"kid": "IiippFPBuNxxxxxxxxxxxxxxxxxxxPDWO9qVEz16tNMOR0"
}.{
"iss": "https://xxxxxxxxxxxxxxxx.b2clogin.com/a861612f-xxxxxxxxxxxxxxxxx14528d/v2.0/",
"exp": 1671546543,
"nbf": 1671542943,
"aud": "b0823952xxxxxxxxxxxxxxxx363b7bdfe0a",
"sub": "c1aceafd-xxxxxxxxxxxxxxxx1f4f1a0a83a7",
"userIdentities": [
{
"issuer": "https://oidc.test.xxxxx.com",
"issuerUserId": "1xxxxxxxxxxxxx9"
},
{
"issuer": "linkedin.com",
"issuerUserId": "xxxxxxxxxx"
},
{
"issuer": "facebook.com",
"issuerUserId": "xxxxxxxxxxxxx"
}
],
"email": "my#email.com",
"name": "My name",
"given_name": "My",
"family_name": "Name",
"idp": "Local",
"tid": "a86161xxxxxxxxxxxxxxxxxxxx4e14528d",
"nonce": "e080be59xxxxxxxxxxxxxxxxxxxx5bfa353bd601",
"scp": "user.read",
"azp": "b0823952xxxxxxxxxxxxx3b7bdfe0a",
"ver": "1.0",
"iat": 1671542943
}.[Signature]
I know that there's several kinds of tokens and it is the access token I need, not ID token or refresh token. The access token from the custom policy flow will be automatically injected into my API calls by MSAL interceptor in the frontend.
None of my specified OutputClaims in my Custom policy are present in the access token. I have also tried adding optionalClaims in my applications manifest in Azure portal like this:
"optionalClaims": {
"idToken": [],
"accessToken": [
{
"name": "email",
"source": "user",
"essential": true,
"additionalProperties": []
}
],
"saml2Token": []
},
I've also tried mail instead of email, and User instead of user.
I am getting access tokens using both implicit grant and username/password flows with the same user, tenant, and application. The problem is the username/password token does not contain the roles and I am unable to verify it. Is there a way I can get a token like the implicit grant flow using the username/password flow? Examples of each are below
implicit Grant Token
{
"aud": "https://<removed>",
"iss": "https://sts.windows.net<removed>",
"iat": 1664909167,
"nbf": 1664909167,
"exp": 1664913508,
"acr": "1",
"aio": "<removed>",
"amr": [
"pwd"
],
"appid": "<removed>",
"appidacr": "1",
"ipaddr": "<removed>",
"name": "Test User",
"oid": "<removed>",
"rh": "<removed>",
"roles": [
"Task.Role1",
"Task.Role2"
],
"scp": "scope1 scope2",
"sub": "<removed>",
"tid": "<removed>",
"unique_name": "testuser#<removed>",
"upn": "testuser#<removed>",
"uti": "<removed>",
"ver": "1.0"
}
Username/Password Token
{
"aud": "00000003-0000-0000-c000-000000000000",
"iss": "https://sts.windows.net/<removed>/",
"iat": 1664909419,
"nbf": 1664909419,
"exp": 1664913431,
"acct": 0,
"acr": "1",
"aio": "<removed>",
"amr": [
"pwd"
],
"app_displayname": "test-api1",
"appid": "<removed>",
"appidacr": "0",
"idtyp": "user",
"ipaddr": "<removed>",
"name": "Test User",
"oid": "<removed>",
"platf": "14",
"puid": "1003200237B425C1",
"rh": "<removed>",
"scp": "User.Read profile openid email",
"sub": "<removed>",
"tenant_region_scope": "NA",
"tid": "<removed>",
"unique_name": "<removed>",
"upn": "<removed>",
"uti": "<removed>",
"ver": "1.0",
"wids": [
"<removed>"
],
"xms_st": {
"sub": "<removed>"
},
"xms_tcdt": 1659020050
}
EDIT...
Below are the scopes in the app
This is the curl command used for the username/password flow. If I specify the scopes in the app, e.g. scope=scope1 scope2, then I get an invalid grant error AADSTS65001: The user or administrator has not consented to use the application with ID. I do not get an error with scope=.default
curl --location --request POST 'https://login.microsoftonline.com/<tenantID>/oauth2/v2.0/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'username=<userID>' \
--data-urlencode 'password=<Password>' \
--data-urlencode 'client_id=<ClientID>' \
--data-urlencode 'scope=.default'
More Edits...
So, this is interesting. I am now getting the auth token with the following code instead of using postman. #azure/msal-node returns both the auth and id tokens. The auth token is the same that is returned from postman and does not contain the roles, however, the id token contains the roles. Why would the auth token not contain the roles and what can I do to fix this?
const msal = require("#azure/msal-node");
const msalConfig = {
auth: {
clientId: "<client id>",
authority: "https://login.microsoftonline.com/<tenant id>",
}
};
const pca = new msal.PublicClientApplication(msalConfig);
const usernamePasswordRequest = {
username: "<username>",
password: "<password>",
};
pca.acquireTokenByUsernamePassword(usernamePasswordRequest).then((response) => {
console.log("response:", response);
}).catch((error) => {
console.log(error);
});
ID token returned from the above code
{
"aud": "<application ID>",
"iss": "https://login.microsoftonline.com/<tenant id>/v2.0",
"iat": 1664986457,
"nbf": 1664986457,
"exp": 1664990357,
"name": "Test User",
"oid": "<removed>",
"preferred_username": "<removed>",
"rh": "<removed>",
"roles": [
"Task.Role1",
"Task.Role2"
],
"sub": "<removed>",
"tid": "<removed>",
"uti": "<removed>",
"ver": "2.0"
}
I have the Azure AD users that are synced from my on-premises AD.
When I updated the user's properties (such as displayName, department, and so on), some users succeeded in updating, but some users failed to update.
In Azure AD, the audit logs of the update successful user and the failed user are as follows.
////////////////// update success user
{
"id": "Directory_xxxxxxx_112926480",
"category": "UserManagement",
"correlationId": "xxxxx",
"result": "success",
"resultReason": "",
"activityDisplayName": "Update user",
"activityDateTime": "2022-02-07T07:03:44.6467812Z",
"loggedByService": "Core Directory",
"operationType": "Update",
"initiatedBy": {
"user": null,
"app": {
"appId": null,
"displayName": "xxxx",
"servicePrincipalId": "xxxx",
"servicePrincipalName": null
}
},
"targetResources": [
{
"id": "xxxx",
"displayName": null,
"type": "User",
"userPrincipalName": "xxxx#xxxx",
"groupType": null,
"modifiedProperties": [
{
"displayName": "Included Updated Properties",
"oldValue": null,
"newValue": "\"\""
},
{
"displayName": "TargetId.UserType",
"oldValue": null,
"newValue": "\"Member\""
}
]
}
],
"additionalDetails": [
{
"key": "UserType",
"value": "Member"
},
{
"key": "User-Agent",
"value": "Apache CXF 3.2.14"
}
]
},
////////////////// update fail user
{
"id": "Directory_xxxx_118537500",
"category": "UserManagement",
"correlationId": "xxxx",
"result": "failure",
"resultReason": "Microsoft.Online.Workflows.PropertyUpdateNotAllowedException",
"activityDisplayName": "Update user",
"activityDateTime": "2022-02-07T07:03:04.9716261Z",
"loggedByService": "Core Directory",
"operationType": "Update",
"initiatedBy": {
"user": null,
"app": {
"appId": null,
"displayName": "xxxx",
"servicePrincipalId": "xxxx",
"servicePrincipalName": null
}
},
"targetResources": [
{
"id": "xxxx",
"displayName": null,
"type": "User",
"userPrincipalName": "xxxx#xxx",
"groupType": null,
"modifiedProperties": [
{
"displayName": "MethodExecutionResult.",
"oldValue": null,
"newValue": "\"Microsoft.Online.Workflows.PropertyUpdateNotAllowedException\""
},
{
"displayName": "TargetId.UserType",
"oldValue": null,
"newValue": "\"Member\""
}
]
}
],
"additionalDetails": [
{
"key": "UserType",
"value": "Member"
},
{
"key": "User-Agent",
"value": "Apache CXF 3.2.14"
}
]
},
Could you tell why the results are so different?
Any help would be appreciated.
Some user details are failed to update because of the error:
Microsoft.Online.Workflows.PropertyUpdateNotAllowedException
The above error usually occurs for many reasons like:
There may be some attributes that violate formatting requirements which restrict characters and character length of attribute values.
The attributes that require unique values may have duplicate attribute values in existing user account (on-prem AD).
May be the user principal name (UPN) was changed after the initial synchronization and must be updated manually.
Some attributes may match exclusion rules for directory synchronization.
The domain value that's used by AD DS attributes hasn't been verified.
To resolve this error, please check the below workarounds if they are helpful:
Use the IdFix DirSync Error Remediation Tool to check for duplicates, missing attributes, and rule violations.
Update AD DS attributes to remove duplicates, rule violations, and scoping exclusions.
Make sure the user properties can’t contain accent characters and the size of displayName, department etc… are under the maximum limits.
For more information in detail, go through below references.
References:
One or more objects don't sync when the Azure Active Directory Sync tool is used - Active Directory | Microsoft Docs
Troubleshoot directory synchronization errors with event 6941 - Office 365 | Microsoft Docs
I added groups claim to both access and id tokens.
image: groups claims added to both token on portal
I also confirmed they are defined in the manifest and groupMembershipClaims = SecurityGroup:
"groupMembershipClaims": "SecurityGroup",
"optionalClaims": {
"idToken": [
{
"name": "groups",
"source": null,
"essential": false,
"additionalProperties": []
}
],
"accessToken": [
{
"name": "groups",
"source": null,
"essential": false,
"additionalProperties": []
}
],
"saml2Token": []
},
When I fetch the tokens.
The groups claim is in the id token, but not in the access token. Is this an ADD bug? I have spent hours in googling and trying. Nothing worked for me so far.
Access Token
"oid": "ab7160f43-3595-4b82-abad-3a750ds95b039",
"platf": "3",
"puid": "100322000B4FFA971",
"scp": "openid profile email",
"sub": "Dd9iRENxMc6sFSOLpqvW-dfLQGgDDUiBvuk4M9PsVus8",
"tid": "2ed2c5sdf-19e7-4eb3-bfb7-eb26560fb1cc",
"unique_name": "xxxxxxxxxxx",
"uti": "D9cxwcvwRUCqmuLTbdd4IOAA",
"ver": "1.0",
"wids": [
"62e90394-69f5-4237-9190-012a177145310",
"9b895d92-2cd3-44c7-9d02-a6ac2d5eag2c3",
"c4e39bd9-1100-46d3-8c65-fb16d0da0071f"
],
"xms_st": {
"sub": "KH969M9F0-jgY2_dA89JzIkvDnt-OsBqltYKxnZv1qc"
},
"xms_tcdt": 1587429781
}.[Signature]
Id token
"iat": 1590181245t,
"nbf": 15901821456,
"exp": 15901855353,
"groups": [
"636c4e93-0a20-419a-9294-df537346bcda3",
"837c721c-83e6-4e20-8a35-2545d53043b28",
"95d05d16-f75a-415a-9c22-846b361777bcd",
"e1c42670-0726-4e5d-a9bd-8be2cc8776c55",
"d324302a-470c-4236-b818-c7706f840dc3",
"ba6f4d61-3927-452e-b2fe-90a5486033537"
],
"idp": "xxxxxx",
"sub": "KH969M9dF0-jgY2_dA89JzIkvDnH-OsBqltYKrxnZv1qc",
"tid": "2ed2tc5df-19e7-4e2b3-bfsb7-eb26a560fb1cc",
"uti": "D9cxwcvwRUCqmruLTb4IOAA",
"ver": "2.0",
"wids": [
When you say you want groups in the access token, that only applies to access tokens meant for that app. The access token you show is probably not meant for your app, but another API, that has not defined that it wants groups in the token.
If you need group info in the front-end application, get them from id token.
If you need them in back-end, you need to acquire a token for your API, and define that you want groups in the access tokens for that API.
You define the API the token is for with the resource/scope parameter when acquiring a token.
If you are using v1 endpoint, you define the client id or app ID URI as the resource.
If you are using v2 endpoint, then you use the scopes defined in the Expose an API tab of the API app registration.
I am deploying an new metric alert to Azure with an ARM template.
I am following the exact same way of Microsoft doc.
With the only change that I deploy just 1 metric to an Automation account and not to an storage account
Template file
"variables": {
"criterion1": "[array(parameters('criterion1'))]",
"criteria": "[concat(variables('criterion1'))]"
},
"resources": [
{
"name": "[parameters('alertName')]",
"type": "Microsoft.Insights/metricAlerts",
"location": "global",
"apiVersion": "2018-03-01",
"tags": {},
"properties": {
"description": "[parameters('alertDescription')]",
"severity": "[parameters('alertSeverity')]",
"enabled": "[parameters('isEnabled')]",
"scopes": [
"[parameters('resourceId')]"
],
"evaluationFrequency": "[parameters('evaluationFrequency')]",
"windowSize": "[parameters('windowSize')]",
"criteria": {
"odata.type": "Microsoft.Azure.Monitor.SingleResourceMultipleMetricCriteria",
"allOf": "[variables('criteria')]"
},
"actions": [
{}
]
}
}
]
parameter file
"criterion1": {
"value": {
"name": "1st criterion",
"metricName": "TotalJob",
"dimensions": [
{
"name": "Status",
"operator": "Include",
"values": [
"Failed"
]
},
{
"name": "Status",
"operator": "Include",
"values": [
"Completed"
]
}
],
"operator": "GreaterThan",
"threshold": "5",
"timeAggregation": "Total"
}
}
But when i deploy this to Azure my Powershell command get stuck without giving any errors even with -DeploymentDebugLogLevel All parameter on it. In Azure portal I got the error "Internal server error" without any context. The json log gives me following logs:
{
"authorization": {
"action": "Microsoft.Insights/metricAlerts/write",
"scope": "/subscriptions/xxxxxx/resourcegroups/bilalachahbar/providers/Microsoft.Insights/metricAlerts/New Metric Alert"
},
"caller": "xxxx",
"channels": "Operation",
"claims": {
"aud": "https://management.azure.com/",
"iss": "https://sts.windows.net/17b5a1d-057c-4ac-a15a-08758f7a7064/",
"iat": "15596014",
"nbf": "15596014",
"exp": "15599914",
"aio": "42RgYDgypS7rfe/Of0l1R+q3TbCgA=",
"appid": "0e4a093a-c6fd-4fba-b4e5-f07ba479f203",
"appidacr": "1",
"http://schemas.microsoft.com/identity/claims/identityprovider": "https://sts.windows.net/17xxxxxc5-a15a-08758f7a7064/",
"http://schemas.microsoft.com/identity/claims/objectidentifier": "a3db39bf-8c65-4b84-b049-d7af99bfb3e",
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier": "a3db39bf-8c65-4b84-b049-d7af99bfb3e",
"http://schemas.microsoft.com/identity/claims/tenantid": "1xxxxxx057c-4ac5-a15a-087f7a7064",
"uti": "SCkIk235EScz0Hst20AA",
"ver": "1.0"
},
"correlationId": "8013b5-9788-41ed-afcf-0dbd8276349c",
"description": "",
"eventDataId": "e39509-0837-4435-af7a-02ba1462055f",
"eventName": {
"value": "EndRequest",
"localizedValue": "End request"
},
"category": {
"value": "Administrative",
"localizedValue": "Administrative"
},
"eventTimestamp": "2018-12-27T14:11:48.1462445Z",
"id": "/subscriptions/xxxxx/resourcegroups/xxxxxx/providers/Microsoft.Insights/metricAlerts/New+Metric+Alert/events/e39509-0837-4435-af7a-02ba1462055f/ticks/815167081462445",
"level": "Error",
"operationId": "e390389-ecc1-4a2-8c2-d94ea635cb",
"operationName": {
"value": "Microsoft.Insights/metricAlerts/write",
"localizedValue": "Create or update metric alert"
},
"resourceGroupName": "xxxxx",
"resourceProviderName": {
"value": "Microsoft.Insights",
"localizedValue": "Microsoft Insights"
},
"resourceType": {
"value": "Microsoft.Insights/metricAlerts",
"localizedValue": "Microsoft.Insights/metricAlerts"
},
"resourceId": "/subscriptions/xxxxxx/resourcegroups/bilalachahbar/providers/Microsoft.Insights/metricAlerts/New Metric Alert",
"status": {
"value": "Failed",
"localizedValue": "Failed"
},
"subStatus": {
"value": "InternalServerError",
"localizedValue": "Internal Server Error (HTTP Status Code: 500)"
},
"submissionTimestamp": "2018-12-27T14:12:05.0719055Z",
"subscriptionId": "xxxxxx",
"properties": {
"statusCode": "InternalServerError",
"serviceRequestId": "8613b5-9788-41d-afcf-0dbd27639c",
"statusMessage": "{\"error\":{\"code\":\"InternalServerError\",\"message\":\"The server encountered an internal error, please retry. If the problem persists, contact support.\"}}"
},
"relatedEvents": []
}
An other stack overflow question got an sort of same question.
He got the problem when using an resource that is not supported anymore but I guess that is not the case with me because the official MS documentation is from september this year. I got the same issues when I use the exact same arm template that is provided in the documentation
I found my own error
Action groups are required when you want to deploy metric alerts.
As you can see in the documentation they provide an action ID, and I didn't. As I thought that it wasn't necessary it actually is.
I know this is obvious but unfortunately I did not saw this in the documentation or in the error. After some debugging and looking in the Resource Explorer I've noticed this.
SO future reader I hope this will solve your issue
One little feedback is that there is no depends on value ATM so I can not create an action group resource first in the same arm template