|
5 | 5 | // This file implements Authorization Server Metadata. |
6 | 6 | // See https://www.rfc-editor.org/rfc/rfc8414.html. |
7 | 7 |
|
| 8 | +//go:build mcp_go_client_oauth |
| 9 | + |
8 | 10 | package oauthex |
9 | 11 |
|
10 | 12 | import ( |
11 | 13 | "bytes" |
12 | 14 | "context" |
13 | 15 | "encoding/json" |
14 | | - "errors" |
15 | 16 | "fmt" |
16 | 17 | "io" |
17 | 18 | "net/http" |
18 | 19 | "time" |
19 | 20 | ) |
20 | 21 |
|
21 | | -// AuthServerMeta represents the metadata for an OAuth 2.0 authorization server, |
22 | | -// as defined in [RFC 8414]. |
23 | | -// |
24 | | -// Not supported: |
25 | | -// - signed metadata |
26 | | -// |
27 | | -// [RFC 8414]: https://tools.ietf.org/html/rfc8414) |
28 | | -type AuthServerMeta struct { |
29 | | - // GENERATED BY GEMINI 2.5. |
30 | | - |
31 | | - // Issuer is the REQUIRED URL identifying the authorization server. |
32 | | - Issuer string `json:"issuer"` |
33 | | - |
34 | | - // AuthorizationEndpoint is the REQUIRED URL of the server's OAuth 2.0 authorization endpoint. |
35 | | - AuthorizationEndpoint string `json:"authorization_endpoint"` |
36 | | - |
37 | | - // TokenEndpoint is the REQUIRED URL of the server's OAuth 2.0 token endpoint. |
38 | | - TokenEndpoint string `json:"token_endpoint"` |
39 | | - |
40 | | - // JWKSURI is the REQUIRED URL of the server's JSON Web Key Set [JWK] document. |
41 | | - JWKSURI string `json:"jwks_uri"` |
42 | | - |
43 | | - // RegistrationEndpoint is the RECOMMENDED URL of the server's OAuth 2.0 Dynamic Client Registration endpoint. |
44 | | - RegistrationEndpoint string `json:"registration_endpoint,omitempty"` |
45 | | - |
46 | | - // ScopesSupported is a RECOMMENDED JSON array of strings containing a list of the OAuth 2.0 |
47 | | - // "scope" values that this server supports. |
48 | | - ScopesSupported []string `json:"scopes_supported,omitempty"` |
49 | | - |
50 | | - // ResponseTypesSupported is a REQUIRED JSON array of strings containing a list of the OAuth 2.0 |
51 | | - // "response_type" values that this server supports. |
52 | | - ResponseTypesSupported []string `json:"response_types_supported"` |
53 | | - |
54 | | - // ResponseModesSupported is a RECOMMENDED JSON array of strings containing a list of the OAuth 2.0 |
55 | | - // "response_mode" values that this server supports. |
56 | | - ResponseModesSupported []string `json:"response_modes_supported,omitempty"` |
57 | | - |
58 | | - // GrantTypesSupported is a RECOMMENDED JSON array of strings containing a list of the OAuth 2.0 |
59 | | - // grant type values that this server supports. |
60 | | - GrantTypesSupported []string `json:"grant_types_supported,omitempty"` |
61 | | - |
62 | | - // TokenEndpointAuthMethodsSupported is a RECOMMENDED JSON array of strings containing a list of |
63 | | - // client authentication methods supported by this token endpoint. |
64 | | - TokenEndpointAuthMethodsSupported []string `json:"token_endpoint_auth_methods_supported,omitempty"` |
65 | | - |
66 | | - // TokenEndpointAuthSigningAlgValuesSupported is a RECOMMENDED JSON array of strings containing |
67 | | - // a list of the JWS signing algorithms ("alg" values) supported by the token endpoint for |
68 | | - // the signature on the JWT used to authenticate the client. |
69 | | - TokenEndpointAuthSigningAlgValuesSupported []string `json:"token_endpoint_auth_signing_alg_values_supported,omitempty"` |
70 | | - |
71 | | - // ServiceDocumentation is a RECOMMENDED URL of a page containing human-readable documentation |
72 | | - // for the service. |
73 | | - ServiceDocumentation string `json:"service_documentation,omitempty"` |
74 | | - |
75 | | - // UILocalesSupported is a RECOMMENDED JSON array of strings representing supported |
76 | | - // BCP47 [RFC5646] language tag values for display in the user interface. |
77 | | - UILocalesSupported []string `json:"ui_locales_supported,omitempty"` |
78 | | - |
79 | | - // OpPolicyURI is a RECOMMENDED URL that the server provides to the person registering |
80 | | - // the client to read about the server's operator policies. |
81 | | - OpPolicyURI string `json:"op_policy_uri,omitempty"` |
82 | | - |
83 | | - // OpTOSURI is a RECOMMENDED URL that the server provides to the person registering the |
84 | | - // client to read about the server's terms of service. |
85 | | - OpTOSURI string `json:"op_tos_uri,omitempty"` |
86 | | - |
87 | | - // RevocationEndpoint is a RECOMMENDED URL of the server's OAuth 2.0 revocation endpoint. |
88 | | - RevocationEndpoint string `json:"revocation_endpoint,omitempty"` |
89 | | - |
90 | | - // RevocationEndpointAuthMethodsSupported is a RECOMMENDED JSON array of strings containing |
91 | | - // a list of client authentication methods supported by this revocation endpoint. |
92 | | - RevocationEndpointAuthMethodsSupported []string `json:"revocation_endpoint_auth_methods_supported,omitempty"` |
93 | | - |
94 | | - // RevocationEndpointAuthSigningAlgValuesSupported is a RECOMMENDED JSON array of strings |
95 | | - // containing a list of the JWS signing algorithms ("alg" values) supported by the revocation |
96 | | - // endpoint for the signature on the JWT used to authenticate the client. |
97 | | - RevocationEndpointAuthSigningAlgValuesSupported []string `json:"revocation_endpoint_auth_signing_alg_values_supported,omitempty"` |
98 | | - |
99 | | - // IntrospectionEndpoint is a RECOMMENDED URL of the server's OAuth 2.0 introspection endpoint. |
100 | | - IntrospectionEndpoint string `json:"introspection_endpoint,omitempty"` |
101 | | - |
102 | | - // IntrospectionEndpointAuthMethodsSupported is a RECOMMENDED JSON array of strings containing |
103 | | - // a list of client authentication methods supported by this introspection endpoint. |
104 | | - IntrospectionEndpointAuthMethodsSupported []string `json:"introspection_endpoint_auth_methods_supported,omitempty"` |
105 | | - |
106 | | - // IntrospectionEndpointAuthSigningAlgValuesSupported is a RECOMMENDED JSON array of strings |
107 | | - // containing a list of the JWS signing algorithms ("alg" values) supported by the introspection |
108 | | - // endpoint for the signature on the JWT used to authenticate the client. |
109 | | - IntrospectionEndpointAuthSigningAlgValuesSupported []string `json:"introspection_endpoint_auth_signing_alg_values_supported,omitempty"` |
110 | | - |
111 | | - // CodeChallengeMethodsSupported is a RECOMMENDED JSON array of strings containing a list of |
112 | | - // PKCE code challenge methods supported by this authorization server. |
113 | | - CodeChallengeMethodsSupported []string `json:"code_challenge_methods_supported,omitempty"` |
114 | | -} |
115 | | - |
116 | 22 | // ClientRegistrationMetadata represents the client metadata fields for the DCR POST request (RFC 7591). |
117 | 23 | type ClientRegistrationMetadata struct { |
118 | 24 | // RedirectURIs is a REQUIRED JSON array of redirection URI strings for use in |
@@ -260,41 +166,6 @@ func (e *ClientRegistrationError) Error() string { |
260 | 166 | return fmt.Sprintf("registration failed: %s (%s)", e.ErrorCode, e.ErrorDescription) |
261 | 167 | } |
262 | 168 |
|
263 | | -var wellKnownPaths = []string{ |
264 | | - "/.well-known/oauth-authorization-server", |
265 | | - "/.well-known/openid-configuration", |
266 | | -} |
267 | | - |
268 | | -// GetAuthServerMeta issues a GET request to retrieve authorization server metadata |
269 | | -// from an OAuth authorization server with the given issuerURL. |
270 | | -// |
271 | | -// It follows [RFC 8414]: |
272 | | -// - The well-known paths specified there are inserted into the URL's path, one at time. |
273 | | -// The first to succeed is used. |
274 | | -// - The Issuer field is checked against issuerURL. |
275 | | -// |
276 | | -// [RFC 8414]: https://tools.ietf.org/html/rfc8414 |
277 | | -func GetAuthServerMeta(ctx context.Context, issuerURL string, c *http.Client) (*AuthServerMeta, error) { |
278 | | - var errs []error |
279 | | - for _, p := range wellKnownPaths { |
280 | | - u, err := prependToPath(issuerURL, p) |
281 | | - if err != nil { |
282 | | - // issuerURL is bad; no point in continuing. |
283 | | - return nil, err |
284 | | - } |
285 | | - asm, err := getJSON[AuthServerMeta](ctx, c, u, 1<<20) |
286 | | - if err == nil { |
287 | | - if asm.Issuer != issuerURL { // section 3.3 |
288 | | - // Security violation; don't keep trying. |
289 | | - return nil, fmt.Errorf("metadata issuer %q does not match issuer URL %q", asm.Issuer, issuerURL) |
290 | | - } |
291 | | - return asm, nil |
292 | | - } |
293 | | - errs = append(errs, err) |
294 | | - } |
295 | | - return nil, fmt.Errorf("failed to get auth server metadata from %q: %w", issuerURL, errors.Join(errs...)) |
296 | | -} |
297 | | - |
298 | 169 | // RegisterClient performs Dynamic Client Registration according to RFC 7591. |
299 | 170 | func RegisterClient(ctx context.Context, registrationEndpoint string, clientMeta *ClientRegistrationMetadata, c *http.Client) (*ClientRegistrationResponse, error) { |
300 | 171 | if registrationEndpoint == "" { |
|
0 commit comments