microsoft-graph-apiazure-ad-b2cazure-ad-graph-api

AADB2C with Graph API: how to filter users by the nested `identities` collection?


I'm using the Graph API via HTTP. I need to filter on all users that have a signInType of "emailAddress".

I'm using this select: https://graph.microsoft.com/v1.0/users?$select=displayName,accountEnabled,id,identities

which returns:

"value": 
[
  {
    "displayName": "Alice User",
    "accountEnabled": true,
    "id": "abcdef01-0aac-8890-5454-1234567890ab",
    "identities": [
      {
        "signInType": "emailAddress",
        "issuer": "mytenant.onmicrosoft.com",
        "issuerAssignedId": "alice.user@mydomain.xyz"
      },
      {
        "signInType": "userPrincipalName",
        "issuer": "mytenant.onmicrosoft.com",
        "issuerAssignedId": "abcdef01-0aac-8890-5454-1234567890ab@mytenant.onmicrosoft.com"
      }
    ]
  },
  {
    "displayName": "George User",
    "accountEnabled": true,
    "id": "12345678-0bb2-430b-8208-abcdefabcdef",
    "identities": [
      {
        "signInType": "emailAddress",
        "issuer": "mytenant.onmicrosoft.com",
        "issuerAssignedId": "george.user@mydomain.xyz"
      },
      {
        "signInType": "userPrincipalName",
        "issuer": "mytenant.onmicrosoft.com",
        "issuerAssignedId": "12345678-0bb2-430b-8208-abcdefabcdef@mytenant.onmicrosoft.com"
      }
    ]
  },
...
]

When I add this filter to the query, I'm getting an error:

https://graph.microsoft.com/v1.0/users?$select=displayName,accountEnabled,id,identities&$filter=identities/any(id:id/signInType eq 'emailAddress')

{
    "error": {
        "code": "Request_BadRequest",
        "message": "Unsupported property or property value or combination of property and operation occured",
        "innerError": {
            "date": "2025-04-17T20:00:20",
            "request-id": "841c2d30-b453-4b2c-972d-fff6e26ac60d",
            "client-request-id": "841c2d30-b453-4b2c-972d-fff6e26ac60d"
        }
    }
}

I have tried various combinations of the filter, all with no success. I believe it's because identities is itself a collection.

This SO post also appears to be filtering on identities in the same manner (the OP states their first approach works): Microsoft Graph API: oddity with searching a user by identity

However, it's not working for me so I must be doing something wrong.

How can I filter on the nested identities collection so that I can query just users that have a "signInType": "emailAddress"?

Thanks.


Solution

  • There is no supported way in Microsoft Graph API (v1.0 or beta) yet, to directly query users based only on the signInType (e.g., emailAddress) in the identities property of Azure AD B2C Users .

    NOTE: Microsoft Graph API does not support filtering directly on nested collections like identities using the $filter parameter.

    I got the same error message for the below query:

    GET https://graph.microsoft.com/v1.0/users?$select=displayName,accountEnabled,id,identities&$filter=identities/any(id:id/signInType eq 'emailAddress')
    

    enter image description here

    Microsoft Graph API only supports Filtering for entries with a signInType of userName or emailAddress requires a valid issuer and issuerAssignedId but ignores the issuer value. This is by design. For more details Refer this MsDoc.

    Use below query for listing the users:

    GET https://graph.microsoft.com/v1.0/users?$select=displayName,accountEnabled,id,identities
    

    Response:

    enter image description here enter image description here

    For fetching the user whose signInType : emailAddress using valid issuer and issuerAssignedId use below query:

    GET https://graph.microsoft.com/v1.0/users?$filter=identities/any(c:c/issuerAssignedId eq '<issuerAssingedId>' and c/issuer eq '<issuer>')
    

    Response:

    enter image description here enter image description here

    As listing of users without valid issuer and issuerAssignedId is not supported by Microsoft Graph API (via HTTP), So as a Workaround, To fetch those users by filtering it on signInType: 'emailAddress .

    Use below Python code:

    import  requests
    
      
    
    # Replace 'access_token' with your actual access token
    
    access_token  =  '<your-access-token>'
    
    url  =  'https://graph.microsoft.com/v1.0/users?$select=displayName,accountEnabled,id,identities'
    
    headers  = {
    
    'Authorization': f'Bearer {access_token}'
    
    }
    
      
    
    response  =  requests.get(url, headers=headers)
    
      
    
    if  response.status_code  ==  200:
    
    users  =  response.json().get('value', [])
    
    filtered_users  = []
    
      
    
    for  user  in  users:
    
    identities  =  user.get('identities', [])
    
    for  identity  in  identities:
    
    if (
    
    identity.get('signInType') ==  'emailAddress'  and
    
    identity.get('issuer') and
    
    identity.get('issuerAssignedId')
    
    ):
    
    filtered_users.append({
    
    'displayName': user.get('displayName'),
    
    'id': user.get('id'),
    
    'emailAddress': identity.get('issuerAssignedId'),
    
    'issuer': identity.get('issuer')
    
    })
    
    break  # If one matching identity is found, no need to check others
    
      
    
    print("Filtered users:")
    
    for  user  in  filtered_users:
    
    print(user)
    
      
    
    else:
    
    print(f"Request failed with status code {response.status_code}")
    
    print(response.text)
    

    Response:

    enter image description here

    Reference:

    objectIdentity resource type

    List users

    Use the $filter query parameter