Azure / Azure/data-api-builder

[Enh]: Session Context Claim Forwarding

Đang mở
#3,313 0 bình luận 0 reaction 0 người được giao Xem trên GitHub
2.x auth enhancement
Ngôn ngữ chính
C#
Star
1.5k
Fork
370
Merge trung bình
3 ngày 22 giờ
Pull request đã merge (30 ngày)
9

Mô tả

See also: https://github.com/Azure/data-api-builder/issues/3078

## Config (Data Source Options Section)

```json
{
"data-source": {
"database-type": "mssql",
"connection-string": "@env('SQL_CONN')",
"options": {
"set-session-context": true,
"session-context-claims": [ // new
"sub",
"preferred_username",
"realm_access.roles",
"https://example.com/tenant"
]
}
}
}
```

## What?

Add `session-context-claims` under `data-source.options` to control exactly which JWT claims are forwarded to SQL Server's `sp_set_session_context`.

## Why?

Today, when `set-session-context` is `true`, DAB forwards all claims from the authenticated identity. Users have no control over which claims are sent or how nested and namespaced claims are resolved.

A simpler model is to resolve the configured claim path and store its value in `SESSION_CONTEXT` as text. Scalar values are stored as text. Arrays and objects are stored as serialized JSON text. SQL can then use `OPENJSON` and other JSON functions when needed.

## Samples

### Simple string claim

```jsonc
// JWT Payload
{ "sub": "abc123" }
```

```jsonc
// DAB Config
"session-context-claims": [
"sub"
]
```

```sql
-- SESSION_CONTEXT
sub → "abc123"
```

### Named string claim

```jsonc
// JWT Payload
{ "preferred_username": "bob" }
```

```jsonc
// DAB Config
"session-context-claims": [
"preferred_username"
]
```

```sql
-- SESSION_CONTEXT
preferred_username → "bob"
```

### Flat array claim

```jsonc
// JWT Payload
{ "roles": ["admin","writer"] }
```

```jsonc
// DAB Config
"session-context-claims": [
"roles"
]
```

```sql
-- SESSION_CONTEXT (stored as JSON text)
roles → '["admin","writer"]'
```

### Nested array claim

```jsonc
// JWT Payload
{ "realm_access": { "roles": ["editor"] } }
```

```jsonc
// DAB Config
"session-context-claims": [
"realm_access.roles"
]
```

```sql
-- SESSION_CONTEXT (stored as JSON text)
realm_access.roles → '["editor"]'
```

### Namespaced string claim

```jsonc
// JWT Payload
{ "https://example.com/tenant": "contoso" }
```

```jsonc
// DAB Config
"session-context-claims": [
"https://example.com/tenant"
]
```

```sql
-- SESSION_CONTEXT
https://example.com/tenant → "contoso"
```

### Namespaced array claim

```jsonc
// JWT Payload
{ "https://example.com/groups": ["A","B"] }
```

```jsonc
// DAB Config
"session-context-claims": [
"https://example.com/groups"
]
```

```sql
-- SESSION_CONTEXT (stored as JSON text)
https://example.com/groups → '["A","B"]'
```

### Object claim

```jsonc
// JWT Payload
{ "profile": { "name": "Bob", "region": "west" } }
```

```jsonc
// DAB Config
"session-context-claims": [
"profile"
]
```

```sql
-- SESSION_CONTEXT (stored as JSON text)
profile → '{"name":"Bob","region":"west"}'
```

## Spec: `session-context-claims`

* Type: `string[]`
* Default: `null` which means when `set-session-context` is `true`, preserve current behavior and forward all flat claims.
* Entry format: ``

* `` follows the same resolution rules as `rolesPath`: URL prefix means literal key, dot means nested traversal, otherwise literal key.

Behavior:

* Resolve the configured claim from the JWT.
* If the value is a string, number, or boolean, store its text value in `SESSION_CONTEXT`.
* If the value is an array or object, store its serialized JSON text in `SESSION_CONTEXT`.
* If the value is `null`, skip and log at `Debug`.
* SQL can parse stored JSON text using functions such as `OPENJSON`.

Notes:

* `SESSION_CONTEXT` stores scalar SQL values only. Arrays and objects are persisted as JSON text.
* Missing claim: Skip silently and do not fail the request. Log at `Debug` level: `"session-context-claims: claim '{path}' not found in JWT, skipping."`
* `SESSION_CONTEXT` key: Use the full `` string as the key name in `sp_set_session_context`.

## Backward Compatibility

| `set-session-context` | `session-context-claims` | Behavior |
| --------------------- | ------------------------ | -------------------------- |
| `false` | any | No claims forwarded |
| `true` | `null` / omitted | Forward all flat claims |
| `true` | `[]` (empty array) | Forward nothing |
| `true` | `["sub", ...]` | Forward only listed claims |

## Validation

| Case | session-context-claims | set-session-context | database-type | Result |
| ---- | -------------------------------------------- | ------------------- | ------------- | ------------------------------------------------------------------------------------------- |
| 1 | set | false | any | Startup error ("session-context-claims requires set-session-context to be true.") |
| 2 | null, empty, or whitespace entry | true | MSSQL | Startup error |
| 3 | set | true | not MSSQL | Startup warning ("session-context-claims is only supported for MSSQL.") and skip at runtime |
| 4 | null / omitted | true | MSSQL | OK (forward all flat claims) |
| 5 | empty array `[]` | true | MSSQL | OK (forward nothing) |
| 6 | valid entries | true | MSSQL | OK (forward only listed claims) |
| 7 | claim not found in JWT | true | MSSQL | Skip and log at `Debug` |
| 8 | resolved value is string, number, or boolean | true | MSSQL | Store text value |
| 9 | resolved value is array | true | MSSQL | Store serialized JSON text |
| 10 | resolved value is object | true | MSSQL | Store serialized JSON text |
| 11 | resolved value is `null` | true | MSSQL | Skip and log at `Debug` |

## Implementation

### Session Context Flow

```text
SQL query execution
→ GetSessionParamsQuery called (existing)
→ If session-context-claims is null:
→ Forward all flat claims (existing behavior)
→ If session-context-claims is non-null:
→ For each entry "path":
→ Resolve claim value (literal key / dot-path / URL key)
→ If missing: skip, log debug
→ If string, number, or boolean: convert to text and set sp_set_session_context 'path', @value
→ If array or object: serialize as JSON text and set sp_set_session_context 'path', @jsonValue
→ If null: skip and log debug
```

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Hướng nghiên cứu

Bắt đầu từ GetSessionParamsQuery và theo dõi cách data-source.options và set-session-context hiện tạo ra các tham số phiên SQL Server. Sau đó, xác định các đường dẫn liên quan đến việc xác thực cấu hình và ghi log trong thời gian chạy. Công việc được xem là hoàn tất khi các trường hợp xác thực được ghi trong tài liệu, việc phân giải claim-path, tuần tự hóa dạng vô hướng hoặc JSON, khả năng tương thích ngược và hành vi bỏ qua đều hoạt động như đã đặc tả.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
csharp, sql
Lĩnh vực
api, backend, databases
Loại issue
Tính năng
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Ít trao đổi
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
55/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.