discoverAuthServerMetadata discovers the Authorization Server Metadata per RFC 8414 §3.1. When the authorization server issuer URL has a path component, the metadata URL is path-aware. Falls back to root-level and OpenID Connect discovery as a last resort. Path-aware: {origin}/.well-known/oauth-aut
( ctx context.Context, httpClient *http.Client, authServerURL string, )
| 1463 | // Root: {origin}/.well-known/oauth-authorization-server |
| 1464 | // OpenID: {issuer}/.well-known/openid-configuration |
| 1465 | func discoverAuthServerMetadata( |
| 1466 | ctx context.Context, httpClient *http.Client, authServerURL string, |
| 1467 | ) (*authServerMetadata, error) { |
| 1468 | parsed, err := url.Parse(authServerURL) |
| 1469 | if err != nil { |
| 1470 | return nil, xerrors.Errorf( |
| 1471 | "parse auth server URL: %w", err, |
| 1472 | ) |
| 1473 | } |
| 1474 | asOrigin := fmt.Sprintf( |
| 1475 | "%s://%s", parsed.Scheme, parsed.Host, |
| 1476 | ) |
| 1477 | asPath := parsed.Path |
| 1478 | |
| 1479 | var urls []string |
| 1480 | |
| 1481 | // Per RFC 8414 §3.1, if the issuer URL has a path, |
| 1482 | // insert the well-known prefix before the path. |
| 1483 | if asPath != "" && asPath != "/" { |
| 1484 | urls = append( |
| 1485 | urls, |
| 1486 | asOrigin+"/.well-known/oauth-authorization-server"+asPath, |
| 1487 | ) |
| 1488 | } |
| 1489 | // Root-level fallback. |
| 1490 | urls = append( |
| 1491 | urls, |
| 1492 | asOrigin+"/.well-known/oauth-authorization-server", |
| 1493 | ) |
| 1494 | // OpenID Connect discovery as a last resort. Note: this is |
| 1495 | // tried after RFC 8414 (unlike the previous mcp-go code that |
| 1496 | // tried OIDC first) because RFC 8414 is the MCP spec's |
| 1497 | // recommended discovery mechanism. |
| 1498 | // Per OpenID Connect Discovery 1.0 §4, the well-known URL |
| 1499 | // is formed by appending to the full issuer (including |
| 1500 | // path), not just the origin. |
| 1501 | urls = append( |
| 1502 | urls, |
| 1503 | strings.TrimRight(authServerURL, "/")+ |
| 1504 | "/.well-known/openid-configuration", |
| 1505 | ) |
| 1506 | |
| 1507 | var lastErr error |
| 1508 | for _, u := range urls { |
| 1509 | var meta authServerMetadata |
| 1510 | if err := fetchJSON(ctx, httpClient, u, &meta); err != nil { |
| 1511 | lastErr = err |
| 1512 | continue |
| 1513 | } |
| 1514 | if meta.AuthorizationEndpoint == "" || meta.TokenEndpoint == "" { |
| 1515 | lastErr = xerrors.Errorf( |
| 1516 | "auth server metadata at %s missing required "+ |
| 1517 | "endpoints", u, |
| 1518 | ) |
| 1519 | continue |
| 1520 | } |
| 1521 | return &meta, nil |
| 1522 | } |
no test coverage detected