discoverAuthorizationServer method

Future<AuthServerMetadata> discoverAuthorizationServer(
  1. String authorizationServer
)

Discover authorization-server metadata for an issuer/AS identifier, trying BOTH RFC 8414 (/.well-known/oauth-authorization-server) and OpenID Connect Discovery 1.0 (/.well-known/openid-configuration, PR#797). The OIDC document shares the RFC 8414 field shape, so AuthServerMetadata.fromJson parses either. The first endpoint that returns a valid document wins.

Sets the client's cached metadata so the existing PKCE/token flow (getAuthorizationUrl, exchangeCodeForToken, …) targets the discovered endpoints. No cryptography is performed here — these are metadata fetches.

Implementation

Future<AuthServerMetadata> discoverAuthorizationServer(
    String authorizationServer) async {
  final origin = Uri.parse(authorizationServer).origin;
  final candidates = <Uri>[
    Uri.parse('$origin/.well-known/oauth-authorization-server'),
    Uri.parse('$origin/.well-known/openid-configuration'),
  ];

  OAuthError? lastError;
  for (final url in candidates) {
    try {
      final response = await _httpClient.get(
        url,
        headers: {'Accept': 'application/json'},
      );
      if (response.statusCode != 200) {
        lastError = OAuthError(
          error: 'as_discovery_failed',
          errorDescription: 'AS metadata ($url): ${response.statusCode}',
        );
        continue;
      }
      final json = jsonDecode(response.body) as Map<String, dynamic>;
      final metadata = AuthServerMetadata.fromJson(json);
      _metadata = metadata;
      return metadata;
    } catch (e) {
      lastError = e is OAuthError
          ? e
          : OAuthError(
              error: 'as_discovery_failed',
              errorDescription: 'AS metadata ($url): $e',
            );
    }
  }
  throw lastError ??
      OAuthError(
        error: 'as_discovery_failed',
        errorDescription:
            'No authorization-server metadata found for '
            '$authorizationServer',
      );
}