sendAuthChallenge method

void sendAuthChallenge(
  1. HttpRequest request, {
  2. String? error,
  3. String? errorDescription,
  4. String? resourceMetadataUrl,
  5. String? scope,
})

Send authentication challenge response.

MCP 2025-11-25 (RFC 9728 / SEP-985, incremental scope SEP-835): when the server publishes OAuth Protected Resource metadata, the challenge SHOULD point the client at the well-known document via resource_metadata="<url>" and MAY advertise a required scope= for step-up. Both are additive — omitting them reproduces the prior bare Bearer error=… challenge.

Implementation

void sendAuthChallenge(
  HttpRequest request, {
  String? error,
  String? errorDescription,
  String? resourceMetadataUrl,
  String? scope,
}) {
  request.response.statusCode = 401;

  final params = <String>[];
  if (resourceMetadataUrl != null) {
    params.add('resource_metadata="$resourceMetadataUrl"');
  }
  if (error != null) {
    params.add('error="$error"');
    if (errorDescription != null) {
      params.add('error_description="$errorDescription"');
    }
  }
  if (scope != null && scope.isNotEmpty) {
    params.add('scope="$scope"');
  }
  final challenge = params.isEmpty ? 'Bearer' : 'Bearer ${params.join(', ')}';

  request.response.headers.set('WWW-Authenticate', challenge);
  request.response.headers.set('Content-Type', 'application/json');

  final errorResponse = {
    'error': error ?? 'unauthorized',
    'error_description': errorDescription ?? 'Authentication required',
  };

  request.response.write(jsonEncode(errorResponse));
}