mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-21 04:54:17 +02:00
config algorithm support
This commit is contained in:
parent
85cca273de
commit
4a5a2b6d17
3 changed files with 26 additions and 5 deletions
|
|
@ -53,6 +53,7 @@ from fastmcp.server.auth import BearerAuthProvider
|
|||
auth = BearerAuthProvider(
|
||||
jwks_uri="https://my-identity-provider.com/.well-known/jwks.json",
|
||||
issuer="https://my-identity-provider.com/",
|
||||
algorithm="RS512",
|
||||
audience="my-mcp-server"
|
||||
)
|
||||
|
||||
|
|
@ -74,6 +75,10 @@ mcp = FastMCP(name="My MCP Server", auth=auth)
|
|||
Expected JWT `iss` claim value
|
||||
</ParamField>
|
||||
|
||||
<ParamField body="algorithm" type="str | None">
|
||||
Algorithm for decoding JWT token. Defaults to 'RS256'
|
||||
</ParamField>
|
||||
|
||||
<ParamField body="audience" type="str | None">
|
||||
Expected JWT `aud` claim value
|
||||
</ParamField>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import time
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
from typing import Any, Literal
|
||||
|
||||
import httpx
|
||||
from authlib.jose import JsonWebKey, JsonWebToken
|
||||
|
|
@ -28,6 +28,7 @@ from fastmcp.server.auth.auth import (
|
|||
from fastmcp.utilities.logging import get_logger
|
||||
|
||||
|
||||
|
||||
class JWKData(TypedDict, total=False):
|
||||
"""JSON Web Key data structure."""
|
||||
|
||||
|
|
@ -113,6 +114,7 @@ class RSAKeyPair:
|
|||
Returns:
|
||||
Signed JWT token string
|
||||
"""
|
||||
#TODO : Add support for configurable algorithms
|
||||
jwt = JsonWebToken(["RS256"])
|
||||
|
||||
now = int(time.time())
|
||||
|
|
@ -151,18 +153,19 @@ class RSAKeyPair:
|
|||
class BearerAuthProvider(OAuthProvider):
|
||||
"""
|
||||
Simple JWT Bearer Token validator for hosted MCP servers.
|
||||
Uses RS256 asymmetric encryption. Supports either static public key
|
||||
Uses RS256 asymmetric encryption by default but supports all JWA algorithms. Supports either static public key
|
||||
or JWKS URI for key rotation.
|
||||
|
||||
Note that this provider DOES NOT permit client registration or revocation, or any OAuth flows.
|
||||
It is intended to be used with a control plane that manages clients and tokens.
|
||||
"""
|
||||
|
||||
#TODO: Add support for configurable algorithms 'e.g. algorithm= HS256, ES256, etc.'
|
||||
def __init__(
|
||||
self,
|
||||
public_key: str | None = None,
|
||||
jwks_uri: str | None = None,
|
||||
issuer: str | None = None,
|
||||
algorithm: str | None = None,
|
||||
audience: str | list[str] | None = None,
|
||||
required_scopes: list[str] | None = None,
|
||||
):
|
||||
|
|
@ -173,6 +176,7 @@ class BearerAuthProvider(OAuthProvider):
|
|||
public_key: RSA public key in PEM format (for static key)
|
||||
jwks_uri: URI to fetch keys from (for key rotation)
|
||||
issuer: Expected issuer claim (optional)
|
||||
algorithm: Algorithm to use for verification (optional, defaults to RS256)
|
||||
audience: Expected audience claim - can be a string or list of strings (optional)
|
||||
required_scopes: List of required scopes for access (optional)
|
||||
"""
|
||||
|
|
@ -180,7 +184,12 @@ class BearerAuthProvider(OAuthProvider):
|
|||
raise ValueError("Either public_key or jwks_uri must be provided")
|
||||
if public_key and jwks_uri:
|
||||
raise ValueError("Provide either public_key or jwks_uri, not both")
|
||||
|
||||
|
||||
if not algorithm:
|
||||
algorithm = "RS256"
|
||||
if algorithm not in {"HS256","HS384","HS512","RS256","RS384","RS512", "ES256", "ES384","ES512","PS256","PS384", "PS512"}:
|
||||
raise ValueError(f"Unsupported algorithm: {algorithm}.")
|
||||
|
||||
# Only pass issuer to parent if it's a valid URL, otherwise use default
|
||||
# This allows the issuer claim validation to work with string issuers per RFC 7519
|
||||
try:
|
||||
|
|
@ -196,11 +205,14 @@ class BearerAuthProvider(OAuthProvider):
|
|||
required_scopes=required_scopes,
|
||||
)
|
||||
|
||||
self.algorithm = algorithm
|
||||
self.issuer = issuer
|
||||
self.audience = audience
|
||||
self.public_key = public_key
|
||||
self.jwks_uri = jwks_uri
|
||||
self.jwt = JsonWebToken(["RS256"])
|
||||
|
||||
# TODO : Add support for configurable algorithms
|
||||
self.jwt = JsonWebToken([self.algorithm]) # Use RS256 by default
|
||||
self.logger = get_logger(__name__)
|
||||
|
||||
# Simple JWKS cache
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ class EnvBearerAuthProviderSettings(BaseSettings):
|
|||
public_key: str | None = None
|
||||
jwks_uri: str | None = None
|
||||
issuer: str | None = None
|
||||
algorithm: str | None = None
|
||||
audience: str | None = None
|
||||
required_scopes: list[str] | None = None
|
||||
|
||||
|
|
@ -33,6 +34,7 @@ class EnvBearerAuthProvider(BearerAuthProvider):
|
|||
public_key: str | None | EllipsisType = ...,
|
||||
jwks_uri: str | None | EllipsisType = ...,
|
||||
issuer: str | None | EllipsisType = ...,
|
||||
algorithm: str | None | EllipsisType = ...,
|
||||
audience: str | None | EllipsisType = ...,
|
||||
required_scopes: list[str] | None | EllipsisType = ...,
|
||||
):
|
||||
|
|
@ -43,6 +45,7 @@ class EnvBearerAuthProvider(BearerAuthProvider):
|
|||
public_key: RSA public key in PEM format (for static key)
|
||||
jwks_uri: URI to fetch keys from (for key rotation)
|
||||
issuer: Expected issuer claim (optional)
|
||||
algorithm: Algorithm to use for verification (optional)
|
||||
audience: Expected audience claim (optional)
|
||||
required_scopes: List of required scopes for access (optional)
|
||||
"""
|
||||
|
|
@ -50,6 +53,7 @@ class EnvBearerAuthProvider(BearerAuthProvider):
|
|||
"public_key": public_key,
|
||||
"jwks_uri": jwks_uri,
|
||||
"issuer": issuer,
|
||||
"algorithm": algorithm,
|
||||
"audience": audience,
|
||||
"required_scopes": required_scopes,
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue