Azure / Azure/data-api-builder

[Bug]: Non-anonymous role permissions break queries selecting sibling nested relationship lists (Object/Array error in ExecuteListField)

Offen
#3,749 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
Vorherrschende Sprache
C#
Sterne
1.5k
Forks
370
Ø Merge
3 T. 22 Std.
Gemergte PRs (30 T.)
9

Beschreibung

### What happened?

On DAB 2.0.8 (MSSQL, GraphQL), any query that selects **two or more sibling nested relationship lists** fails with:

```
System.InvalidOperationException: The requested operation requires an element of type 'Object', but the target element has type 'Array'.
at System.Text.Json.JsonElement.TryGetProperty(String propertyName, JsonElement& value)
at Azure.DataApiBuilder.Service.Services.ExecutionHelper.TryGetPropertyFromParent(...) ExecutionHelper.cs:line 350
at Azure.DataApiBuilder.Service.Services.ExecutionHelper.ExecuteListField(...) ExecutionHelper.cs:line 293
...
at HotChocolate.Authorization.AuthorizeMiddleware.InvokeAsync(IMiddlewareContext context)
```

**but only when the entities' permissions use a non-`anonymous` role.** With the identical config where every permission role is `anonymous`, the same query succeeds.

### Repro

Schema shape (SQL Server): `Organization 1-N OrganizationAddress N-M AddressType` and `Organization 1-N OrganizationEmail N-M EmailType` (junction/linking-object relationships).

```graphql
query {
organization_by_pk(id: "...") {
id
addresses { items { id addressTypes { items { id } } } }
emails { items { id emailTypes { items { emailTypeId } } } }
}
}
```

- Config A: all entity permissions `{"role": "anonymous", ...}` → **works** (any auth provider; also works when the request carries `X-MS-API-ROLE: authenticated` under Simulator).
- Config B: byte-identical except every `"role": "anonymous"` replaced with `"role": "authenticated"` (Simulator provider, request sent with `X-MS-API-ROLE: authenticated`) → **fails** with the error above at path `organization_by_pk.addresses.items[0].addressTypes.items`.
- Selecting only ONE of the nested chains (only `addresses.items.addressTypes` OR only `emails.items.emailTypes`) works in both configs.
- Reproduces identically with the EntraID provider and a valid bearer token.
- The error also poisons the response data: the affected relationship resolves to `null` alongside the error.

### Analysis

When permissions use a non-anonymous role, Hot Chocolate attaches `AuthorizeMiddleware` to the DAB-generated fields (visible in the stack). That changes field execution from inline pure resolvers to the classic middleware pipeline with concurrent resolver tasks. DAB's pagination metadata is stashed in shared request `ContextData` under keys derived from root field name + path depth (+ relationship path suffix) — see `ExecutionHelper.GetMetadata` / `SetNewMetadataChildren`. With two sibling nested subtrees resolving concurrently, the lookup for the second-level connection (`addressTypes`) misses (or reads the sibling's entry), falls back to `PaginationMetadata.MakeEmptyPaginationMetadata()`, so the connection wrapper is not applied and the child `items` resolver receives a raw JSON array where it expects the connection object.

The relevant code is unchanged on `main` as of this report, so the issue is not specific to 2.0.8.

### Impact

Role-restricted GraphQL (i.e., actually using DAB authorization — the reason auth exists) breaks on common list+junction selections, while fully-anonymous configs appear fine — so the bug surfaces exactly when hardening permissions.

### Version

- Data API builder 2.0.8 (container and CLI), SQL Server (Azure SQL DB), GraphQL runtime only (REST disabled).

Beitragsleitfaden

Beitragsleitfaden öffnen

Rechercherichtung

Führe die Abfrage mit verschachtelten Geschwisterlisten unter anonymen und authentifizierten Rollen erneut aus und verfolge anschließend ExecutionHelper.cs, insbesondere ExecuteListField, GetMetadata und SetNewMetadataChildren. Prüfe, wie sich die gleichzeitige Ausführung autorisierter Felder auf die Suche nach den Paginierungsmetadaten auswirkt; abgeschlossen ist die Arbeit, wenn die authentifizierte Abfrage beide Beziehungslisten ohne einen Object/Array-Fehler oder null-Daten zurückgibt.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
csharp, graphql, sql
Bereich
api, authorization, backend-api-design, databases
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Ruhig
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
48/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.