Skip to content

Commit 1265032

Browse files
committed
refactor: update usage
1 parent d35b1a7 commit 1265032

15 files changed

Lines changed: 223 additions & 260 deletions

mcpauth/__init__.py

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import logging
2-
from typing import Any, Literal, Union
2+
from typing import List, Literal, Optional, Union
33

4-
from .middleware.create_bearer_auth import BaseBearerAuthConfig, BearerAuthConfig
4+
from .middleware.create_bearer_auth import BearerAuthConfig
55
from .types import VerifyAccessTokenFunction
6-
from .config import MCPAuthConfig
6+
from .config import AuthServerConfig
77
from .exceptions import MCPAuthAuthServerException, AuthServerExceptionCode
88
from .utils import validate_server_config
99
from starlette.middleware.base import BaseHTTPMiddleware
@@ -16,12 +16,14 @@ class MCPAuth:
1616
functions for handling OAuth 2.0-related tasks and bearer token auth.
1717
1818
See Also: https://mcp-auth.dev for more information about the library and its usage.
19-
20-
:param config: An instance of `MCPAuthConfig` containing the server configuration.
2119
"""
2220

23-
def __init__(self, config: MCPAuthConfig):
24-
result = validate_server_config(config.server)
21+
def __init__(self, server: AuthServerConfig):
22+
"""
23+
:param server: Configuration for the remote authorization server.
24+
"""
25+
26+
result = validate_server_config(server)
2527

2628
if not result.is_valid:
2729
logging.error(
@@ -37,13 +39,13 @@ def __init__(self, config: MCPAuthConfig):
3739
for warning in result.warnings:
3840
logging.warning(f"- {warning}")
3941

40-
self.config = config
42+
self.server = server
4143

4244
def metadata_response(self) -> JSONResponse:
4345
"""
4446
Returns a response containing the server metadata in JSON format with CORS support.
4547
"""
46-
server_config = self.config.server
48+
server_config = self.server
4749

4850
response = JSONResponse(
4951
server_config.metadata.model_dump(exclude_none=True),
@@ -56,22 +58,26 @@ def metadata_response(self) -> JSONResponse:
5658
def bearer_auth_middleware(
5759
self,
5860
mode_or_verify: Union[Literal["jwt"], VerifyAccessTokenFunction],
59-
config: BaseBearerAuthConfig = BaseBearerAuthConfig(),
60-
jwt_options: dict[str, Any] = {},
61+
audience: Optional[str] = None,
62+
required_scopes: Optional[List[str]] = None,
63+
show_error_details: bool = False,
64+
leeway: float = 60,
6165
) -> type[BaseHTTPMiddleware]:
6266
"""
6367
Creates a middleware that handles bearer token authentication.
6468
6569
:param mode_or_verify: If "jwt", uses built-in JWT verification; or a custom function that
6670
takes a string token and returns an `AuthInfo` object.
67-
:param config: Configuration for the Bearer auth handler, including audience, required
68-
scopes, etc.
69-
:param jwt_options: Optional dictionary of additional options for JWT verification
70-
(`jwt.decode`). Not used if a custom function is provided.
71+
:param audience: Optional audience to verify against the token.
72+
:param required_scopes: Optional list of scopes that the token must contain.
73+
:param show_error_details: Whether to include detailed error information in the response.
74+
Defaults to `False`.
75+
:param leeway: Optional leeway in seconds for JWT verification (`jwt.decode`). Defaults to
76+
`60`. Not used if a custom function is provided.
7177
:return: A middleware class that can be used in a Starlette or FastAPI application.
7278
"""
7379

74-
metadata = self.config.server.metadata
80+
metadata = self.server.metadata
7581
if isinstance(mode_or_verify, str) and mode_or_verify == "jwt":
7682
from .utils import create_verify_jwt
7783

@@ -82,7 +88,7 @@ def bearer_auth_middleware(
8288

8389
verify = create_verify_jwt(
8490
metadata.jwks_uri,
85-
options=jwt_options,
91+
leeway=leeway,
8692
)
8793
elif callable(mode_or_verify):
8894
verify = mode_or_verify
@@ -94,5 +100,11 @@ def bearer_auth_middleware(
94100
from .middleware.create_bearer_auth import create_bearer_auth
95101

96102
return create_bearer_auth(
97-
verify, BearerAuthConfig(issuer=metadata.issuer, **config.model_dump())
103+
verify,
104+
BearerAuthConfig(
105+
issuer=metadata.issuer,
106+
audience=audience,
107+
required_scopes=required_scopes,
108+
show_error_details=show_error_details,
109+
),
98110
)

mcpauth/config.py

Lines changed: 140 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,148 @@
1-
from .models.auth_server import AuthServerConfig
1+
from enum import Enum
2+
from typing import List, Optional
23
from pydantic import BaseModel
4+
from pydantic import BaseModel
5+
6+
7+
class AuthorizationServerMetadata(BaseModel):
8+
"""
9+
Pydantic model for OAuth 2.0 Authorization Server Metadata as defined in RFC 8414.
10+
"""
11+
12+
issuer: str
13+
"""
14+
The authorization server's issuer identifier, which is a URL that uses the `https` scheme and
15+
has no query or fragment components.
16+
"""
317

18+
authorization_endpoint: str
19+
"""
20+
URL of the authorization server's authorization endpoint [[RFC6749](https://rfc-editor.org/rfc/rfc6749)].
21+
This is REQUIRED unless no grant types are supported that use the authorization endpoint.
22+
23+
See: https://rfc-editor.org/rfc/rfc6749#section-3.1
24+
"""
25+
26+
token_endpoint: str
27+
"""
28+
URL of the authorization server's token endpoint [[RFC6749](https://rfc-editor.org/rfc/rfc6749)].
29+
This is REQUIRED unless only the implicit grant type is supported.
30+
31+
See: https://rfc-editor.org/rfc/rfc6749#section-3.2
32+
"""
433

5-
class MCPAuthConfig(BaseModel):
34+
jwks_uri: Optional[str] = None
635
"""
7-
Configuration for the `MCPAuth` class.
36+
URL of the authorization server's JWK Set [[JWK](https://www.rfc-editor.org/rfc/rfc8414.html#ref-JWK)] document.
37+
The referenced document contains the signing key(s) the client uses to validate signatures
38+
from the authorization server. This URL MUST use the `https` scheme.
839
"""
940

10-
server: AuthServerConfig
41+
registration_endpoint: Optional[str] = None
42+
"""
43+
URL of the authorization server's OAuth 2.0 Dynamic Client Registration endpoint
44+
[[RFC7591](https://www.rfc-editor.org/rfc/rfc7591)].
45+
"""
46+
47+
scope_supported: Optional[List[str]] = None
48+
49+
response_types_supported: List[str]
50+
"""
51+
JSON array containing a list of the OAuth 2.0 `response_type` values that this authorization
52+
server supports. The array values used are the same as those used with the `response_types`
53+
parameter defined by "OAuth 2.0 Dynamic Client Registration Protocol" [[RFC7591](https://www.rfc-editor.org/rfc/rfc7591)].
54+
"""
55+
56+
response_modes_supported: Optional[List[str]] = None
57+
"""
58+
JSON array containing a list of the OAuth 2.0 `response_mode` values that this
59+
authorization server supports, as specified in "OAuth 2.0 Multiple Response Type Encoding Practices"
60+
[[OAuth.Responses](https://datatracker.ietf.org/doc/html/rfc8414#ref-OAuth.Responses)].
61+
62+
If omitted, the default is ["query", "fragment"]. The response mode value `"form_post"` is
63+
also defined in "OAuth 2.0 Form Post Response Mode" [[OAuth.FormPost](https://datatracker.ietf.org/doc/html/rfc8414#ref-OAuth.Post)].
64+
"""
65+
66+
grant_types_supported: Optional[List[str]] = None
67+
"""
68+
JSON array containing a list of the OAuth 2.0 grant type values that this authorization server supports.
69+
The array values used are the same as those used with the `grant_types` parameter defined by
70+
"OAuth 2.0 Dynamic Client Registration Protocol" [[RFC7591](https://www.rfc-editor.org/rfc/rfc7591)].
71+
72+
If omitted, the default value is ["authorization_code", "implicit"].
73+
"""
74+
75+
token_endpoint_auth_methods_supported: Optional[List[str]] = None
76+
token_endpoint_auth_signing_alg_values_supported: Optional[List[str]] = None
77+
service_documentation: Optional[str] = None
78+
ui_locales_supported: Optional[List[str]] = None
79+
op_policy_uri: Optional[str] = None
80+
op_tos_uri: Optional[str] = None
81+
82+
revocation_endpoint: Optional[str] = None
1183
"""
12-
Config for the remote authorization server.
84+
URL of the authorization server's OAuth 2.0 revocation endpoint [[RFC7009](https://www.rfc-editor.org/rfc/rfc7009)].
1385
"""
86+
87+
revocation_endpoint_auth_methods_supported: Optional[List[str]] = None
88+
revocation_endpoint_auth_signing_alg_values_supported: Optional[List[str]] = None
89+
90+
introspection_endpoint: Optional[str] = None
91+
"""
92+
URL of the authorization server's OAuth 2.0 introspection endpoint [[RFC7662](https://www.rfc-editor.org/rfc/rfc7662)].
93+
"""
94+
95+
introspection_endpoint_auth_methods_supported: Optional[List[str]] = None
96+
introspection_endpoint_auth_signing_alg_values_supported: Optional[List[str]] = None
97+
98+
code_challenge_methods_supported: Optional[List[str]] = None
99+
"""
100+
JSON array containing a list of Proof Key for Code Exchange (PKCE) [[RFC7636](https://www.rfc-editor.org/rfc/rfc7636)]
101+
code challenge methods supported by this authorization server.
102+
"""
103+
104+
105+
class AuthServerType(str, Enum):
106+
"""
107+
The type of the authorization server. This information should be provided by the server
108+
configuration and indicates whether the server is an OAuth 2.0 or OpenID Connect (OIDC)
109+
authorization server.
110+
"""
111+
112+
OAUTH = "oauth"
113+
OIDC = "oidc"
114+
115+
116+
class AuthServerConfig(BaseModel):
117+
"""
118+
Configuration for the remote authorization server integrated with the MCP server.
119+
"""
120+
121+
metadata: AuthorizationServerMetadata
122+
"""
123+
The metadata of the authorization server, which should conform to the MCP specification
124+
(based on OAuth 2.0 Authorization Server Metadata).
125+
126+
This metadata is typically fetched from the server's well-known endpoint (OAuth 2.0
127+
Authorization Server Metadata or OpenID Connect Discovery); it can also be provided
128+
directly in the configuration if the server does not support such endpoints.
129+
130+
See:
131+
- OAuth 2.0 Authorization Server Metadata: https://datatracker.ietf.org/doc/html/rfc8414
132+
- OpenID Connect Discovery: https://openid.net/specs/openid-connect-discovery-1_0.html
133+
"""
134+
135+
type: AuthServerType
136+
"""
137+
The type of the authorization server. See `AuthServerType` for possible values.
138+
"""
139+
140+
141+
class ServerMetadataPaths(str, Enum):
142+
"""
143+
Enum for server metadata paths.
144+
This is used to define the standard paths for OAuth and OIDC well-known URLs.
145+
"""
146+
147+
OAUTH = "/.well-known/oauth-authorization-server"
148+
OIDC = "/.well-known/openid-configuration"

mcpauth/middleware/create_bearer_auth.py

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,14 @@
1818
from ..types import VerifyAccessTokenFunction, Record
1919

2020

21-
class BaseBearerAuthConfig(BaseModel):
21+
class BearerAuthConfig(BaseModel):
2222
"""
23-
Base configuration for the Bearer auth handler.
23+
Configuration for the Bearer auth handler.
24+
"""
25+
26+
issuer: str
27+
"""
28+
The expected issuer of the access token. This should be a valid URL.
2429
"""
2530

2631
audience: Optional[str] = None
@@ -42,17 +47,6 @@ class BaseBearerAuthConfig(BaseModel):
4247
"""
4348

4449

45-
class BearerAuthConfig(BaseBearerAuthConfig):
46-
"""
47-
Configuration for the Bearer auth handler.
48-
"""
49-
50-
issuer: str
51-
"""
52-
The expected issuer of the access token. This should be a valid URL.
53-
"""
54-
55-
5650
def get_bearer_token_from_headers(headers: Headers) -> str:
5751
"""
5852
Extract the Bearer token from the request headers.

mcpauth/models/__init__.py

Lines changed: 0 additions & 7 deletions
This file was deleted.

mcpauth/models/auth_server.py

Lines changed: 0 additions & 39 deletions
This file was deleted.

0 commit comments

Comments
 (0)