Yvand/EntraCP

Add Claim type mapping to query 'CompanyName' brake people picker from site

Closed this issue ยท 14 comments

Hello,

I'm facing the following issue.
I add a new Claim type mapping like following:
image

Below if the Claim type information from the SPTrustedIdentityTokenIssuer object:

DisplayName                    : Entity
InputClaimType                 : http://xxx.com/claims/company
MappedClaimType                : http://xxx.com/claims/company
IsIdentityClaim                : False

After an iisreset to get back AzureCP in Central Administration, I lookup for Entity results from CA People picker:
image
So this part is working well.

However, if I try from a SharePoint site, I'm clearly getting a 'No results found' message. No Entity, neither Username or whatever, no result at all.

From ULS logs, I'm getting this:

[AzureCP] Unexpected error occurred Microsoft.Graph could not query tenant 'xxx.onmicrosoft.com': Microsoft.Graph.ServiceException: Code: Request_UnsupportedQuery  Message: Unsupported or invalid query filter clause specified for property 'companyName' of resource 'User'.
[AzureCP] Got 0 users/groups in 71 ms from 'xxx.onmicrosoft.com' with input 'yyy'

I don't know if other attribute other than 'companyName' are affected by this issue. But once I remove this specific Claim type, I recover a functional claim provider on both sides (CA and site).

Yvand commented

@julmsy thank you for reporting this, yes this is an "known" issue: AAD user object has many properties, but not all can be used in a query, but the API does not offer a way (that I could find) to exclude those that cannot be used...

I am able to get the companyName to work. There need some headers to be set for this query to succedd:

https://graph.microsoft.com/v1.0/users/?$filter=startswith(companyName,'This')&$select=companyName&$count=true

Headers:

ConsistencyLevel:eventual

This will return:

{
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users(companyName)",
    "@odata.count": 1,
    "value": [
        {
            "companyName": "This is Chris"
        }
    ]
}

The fix is already part of the dev branch. https://github.com/Yvand/AzureCP/blob/08e88ccd5335b243132b866d5d20300137447ed5/AzureCP/AzureCP.cs#L1395

I'll do some additional testing on my end.

I'm able to reproduce the issue within AzureCP, but not within a console application...

[AzureCP] Unexpected error occurred Microsoft.Graph could not query tenant '.onMicrosoft.com': Microsoft.Graph.ServiceException: Code: Request_UnsupportedQuery  Message: Unsupported or invalid query filter clause specified for property 'companyName' of resource 'User'.  Inner error:   AdditionalData:   date: 2023-02-24T12:30:31   request-id: a04ff637-73d2-4c7b-b70c-9eb6ea01b646   client-request-id: a04ff637-73d2-4c7b-b70c-9eb6ea01b646  , Callstack:   
 at Microsoft.Graph.BatchResponseContent.<GetResponseByIdAsync>d__9`1.MoveNext()  --- End of stack trace from previous location where exception was thrown ---    
 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()    
 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)    
 at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()    
 at azurecp.AzureCP.<>c__DisplayClass60_0.<<QueryAzureADTenantAsync>b__0>d.MoveNext()  --- End of stack trace from previous location where exception was thrown ---    
 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()    
 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)    
 at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()    
 at azurecp.AzureCP.<QueryAzureADTenantAsync>d__60.MoveNext()

Below the simplified console application to query MS Graph.


            var graphClient = new GraphServiceClient(clientSecretCredential, scopes);


            List<Option> queryOptions = new List<Option>
                        {
                            new QueryOption("$count", "true"),
                            new HeaderOption ("ConsistencyLevel", "eventual")
                        };

            var users = graphClient.Users
                .Request(queryOptions)
                .Select("UserType, Mail, UserPrincipalName, extension_5432193b8b4f4878ab493feb411affa4_extensionAttribute15, CompanyName, DisplayName, GivenName, Surname, Mail, DisplayName, Mail, MobilePhone, JobTitle, Department, OfficeLocation")
                .Filter("( (startswith(UserPrincipalName, 'thi') and UserType eq 'Member') or (startswith(Mail, 'thi') and UserType eq 'Guest') ) or startswith(extension_5432193b8b4f4878ab493feb411affa4_extensionAttribute15, 'thi') or startswith(CompanyName, 'thi') or startswith(DisplayName, 'thi') or startswith(GivenName, 'thi') or startswith(Surname, 'thi') or startswith(Mail, 'thi')")
                .Top(30)
                .GetAsync()
                .Result;

            Console.WriteLine(users.Count);
            foreach(var u in users)
            {
                Console.WriteLine("User:");
                Console.WriteLine(u.UserPrincipalName);
                Console.WriteLine(u.CompanyName);
            }
            
            Console.ReadLine();
Yvand commented

@andikrueger I actually added the header ConsistencyLevel:eventual about 2 months ago in e12db1e so this issue should be fixed (in dev branch)

Iโ€™m aware of this change and am still seeing this issue.
running the code in a console application works fine. Somehow AzureCP has another outcome of the code.

Yvand commented

Ok, I will test it

Yvand commented

I repro, I'll investigate and update this issue

Yvand commented

So the previous fix did not work in batched requests.
PR #177 now correctly sets the header ConsistencyLevel eventual on batched requests, but what a pain to fix it...

Thanks @Yvand !
I'm waiting a new dev version, then I'll proceed a bunch of tests.

Yvand commented

@julmsy you can already test it by downloading the artifact here

Yvand commented

@julmsy I did not realize that artifacts produced by a GitHub workflow requires authentication to be downloaded.
So now I create a nightly release which always contains the latest version compiled, in case you still want to test it

Thanks @Yvand.
In fact I compiled AzureCP solution from fix-advanced-queries-in-batching branch, and started to do some tests on it. The Claim type mapping to query 'CompanyName' is now working well.
However I discovered another issue, but for now I'm not sure if it's related to AzureCP or our environment, I need to proceed more tests.

Yvand commented

Please keep me posted about this issue when you have more details. Thanks!

julmsy commented

Hello @Yvand, for that case I confirm that it works nicely now (Nightly Release 20230426).
So I think we can close that one.