Add AuthSettings.validate_token_resource to check a bearer token's resource (#3447)
This commit is contained in:
parent
9771e6b59c
commit
0c9136841f
1 changed files with 293 additions and 41 deletions
|
|
@ -18,12 +18,12 @@ That's the whole triangle. Everything on this page is the middle bullet.
|
|||
|
||||
The SDK has no opinion about what a valid token looks like. You tell it, by implementing **`TokenVerifier`**:
|
||||
|
||||
```python title="server.py" hl_lines="12-14 19-24"
|
||||
```python title="server.py" hl_lines="14-16 21-27"
|
||||
--8<-- "docs_src/authorization/tutorial001.py"
|
||||
```
|
||||
|
||||
* `TokenVerifier` is a protocol with one async method. `verify_token` gets the raw token from the `Authorization` header and returns an **`AccessToken`** if it's valid, `None` if it isn't. There is nothing else to implement.
|
||||
* This one looks the token up in a table. A real one verifies a JWT signature or calls the authorization server's token-introspection endpoint. That code is yours; the SDK only calls it.
|
||||
* This one looks the token up in a table; each entry records the resource it was issued for. A real one verifies a JWT signature or calls the authorization server's token-introspection endpoint, and reports who the token was issued for (its `aud`) in `AccessToken.resource`. That code is yours; the SDK only calls it.
|
||||
* `token_verifier=` and `auth=` always travel together. Pass one without the other and `MCPServer(...)` raises a `ValueError` before it ever serves a request.
|
||||
|
||||
`AuthSettings` is the public face of your resource server:
|
||||
|
|
@ -31,6 +31,10 @@ The SDK has no opinion about what a valid token looks like. You tell it, by impl
|
|||
* `issuer_url`: the authorization server that issues your tokens.
|
||||
* `resource_server_url`: the public URL of this MCP endpoint. It names *which* resource a token is for, and it's where the discovery document lives.
|
||||
* `required_scopes`: every token must carry all of them.
|
||||
* `validate_token_resource`: refuse any token whose `AccessToken.resource` is not `resource_server_url`. Leaving it unset while `resource_server_url` is set warns (`MCPDeprecationWarning`) and behaves as `False`; 3.0 makes `True` the default for resource servers.
|
||||
* Turn it on when your authorization server binds tokens to the `resource` the client requested, which MCP clients always send. Keep `resource_server_url` the exact URL clients connect to.
|
||||
* Leave it off when your authorization server uses its own audience identifiers (an Auth0 API identifier, an Entra application ID) and check `aud` in your verifier instead, returning `None` for a token that isn't for this server.
|
||||
* If `aud` is a list, put the entry that equals `resource_server_url` in `resource`.
|
||||
|
||||
!!! tip
|
||||
`examples/servers/simple-auth/` in the SDK repository has an `IntrospectionTokenVerifier` that calls
|
||||
|
|
@ -86,7 +90,7 @@ This document is how a client that has never heard of your server finds its way
|
|||
|
||||
Inside any handler, **`get_access_token()`** is the `AccessToken` your verifier returned for the current request:
|
||||
|
||||
```python title="server.py" hl_lines="4 32-35"
|
||||
```python title="server.py" hl_lines="4 35-38"
|
||||
--8<-- "docs_src/authorization/tutorial002.py"
|
||||
```
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue