Исправление конфигурации OpenID для MCP-коннекторов
На этой неделе я потратил слишком много времени на исправление удаленного MCP-коннектора.
Коннектор постоянно не мог найти мой OAuth-сервер. При этом сервер работал исправно. Проблема заключалась в одном отсутствующем маршруте и редиректе.
Когда вы используете OAuth с MCP, вы ожидаете, что документы обнаружения (discovery documents) будут работать. Большинство инструментов ищут следующие два пути:
- /.well-known/oauth-authorization-server
- /.well-known/oauth-protected-resource
Они указывают клиентам, где найти эндпоинты авторизации и токенов.
Проблема в том, что многие клиенты не ищут эти конкретные пути. Вместо этого они ищут /.well-known/openid-configuration.
Это путь OpenID Connect. Это другая спецификация, но она находится в том же месте. Мой пакет не регистрировал этот путь, так как он следует спецификации OAuth, а не OIDC.
Клиент стучится в дверь, которой не существует. Он получает ошибку 404 и завершает работу.
У меня было два варианта:
Использовать редирект через обратный прокси-сервер в Nginx. Это «ленивое» решение. Оно выносит логику из вашего кода в инфраструктуру. Его сложно тестировать, и его легко сломать во время развертывания.
Исправить это внутри приложения. Это более правильный путь.
Я решил заставить приложение отвечать на этот запрос. Я создал алиас, который перенаправляет путь OpenID на путь авторизации OAuth.
Я использовал 308 Permanent Redirect.
Редирект 302 может изменить POST-запрос на GET-запрос. Редирект 308 работает строго: он указывает клиенту перейти по новому URL, сохранив тот же метод и тело запроса. Это правильный способ обработки постоянного перемещения.
Я также вынес это под флаг конфигурации. Это позволяет пользователям отключить его, если они используют собственное обнаружение OIDC.
Реализовав это в коде, я могу написать тесты:
- Один тест проверяет, правильно ли происходит редирект.
- Один тест следует за редиректом, чтобы убедиться, что метаданные валидны.
Это гарантирует, что если структура метаданных изменится, мои тесты сразу же упадут. Я обнаружу ошибку в своем пайплайне, а не тогда, когда пользователь не сможет подключиться.
На практике спецификации часто различаются. Даже если два стандарта преследуют схожие цели, клиенты могут выбирать разные пути. Как разработчик сервера, вы должны «открывать обе двери».
Направляйте их в одну и ту же комнату, используйте правильный код редиректа и подкрепляйте это тестами.
Известный псевдоним конфигурации OpenID, благодаря которому MCP-коннекторы работают «из коробки»
Если вы когда-либо работали с OAuth2 или OpenID Connect (OIDC), вы наверняка сталкивались с эндпоинтом .well-known/openid-configuration.
Этот эндпоинт является стандартной частью спецификации OIDC и служит для автоматического обнаружения (discovery) метаданных провайдера идентификации (Identity Provider, IdP).
В этой статье мы обсудим, как использование этого стандартного механизма может значительно упростить создание и использование MCP-коннекторов (Model Context Protocol).
Что такое MCP?
Model Context Protocol (MCP) — это открытый стандарт, который позволяет ИИ-моделям (LLM) беспрепятственно подключаться к внешним инструментам и данным. MCP-коннекторы выступают в роли моста между моделью и сторонними сервисами.
Проблема: Сложность настройки аутентификации
Многие современные сервисы требуют аутентификации через OAuth2 или OIDC. Когда вы создаете MCP-коннектор для такого сервиса, вам необходимо предоставить клиенту (например, Claude Desktop) ряд параметров:
issuer(издатель)authorization_endpoint(эндпоинт авторизации)token_endpoint(эндпоинт токенов)jwks_uri(URI ключей JWK)- ...и многие другие.
Это создает неудобный пользовательский опыт. Пользователю приходится вручную копировать и вставлять множество URL-адресов, что увеличивает вероятность ошибки.
Решение: Использование .well-known/openid-configuration
Вместо того чтобы требовать от пользователя ввода всех эндпоинтов, мы можем попросить только один параметр: issuer URL.
Согласно спецификации OIDC, если клиент знает URL издателя (например, https://auth.example.com), он может автоматически найти все остальные параметры, просто добавив к нему путь .well-known/openid-configuration.
Как это работает
- Пользователь предоставляет только
issuer:https://auth.example.com. - MCP-коннектор делает GET-запрос к
https://auth.example.com/.well-known/openid-configuration. - Сервер возвращает JSON-объект с метаданными:
{
"issuer": "https://auth.example.com",
"authorization_endpoint": "https://auth.example.com/authorize",
"token_endpoint": "https://auth.example.com/token",
"userinfo_endpoint": "https://auth.example.com/userinfo",
"jwks_uri": "https://auth.example.com/keys",
"scopes_supported": ["openid", "profile", "email"],
"response_types_supported": ["code"]
}
- MCP-коннектор автоматически извлекает нужные эндпоинты и использует их для процесса OAuth2.
Преимущества для MCP-коннекторов
- Упрощенная настройка: Пользователю нужно знать только один URL.
- Надежность: Меньше шансов ошибиться при ручном вводе длинных URL.
- Гибкость: Если провайдер обновит свои эндпоинты, коннектор автоматически подхватит новые данные без изменения конфигурации на стороне пользователя.
- Соответствие стандартам: Это использование проверенного временем стандарта OIDC.
Заключение
Использование .well-known/openid-configuration — это простой, но мощный способ сделать MCP-коннекторы более удобными и надежными. Вместо того чтобы заставлять пользователей возиться с деталями реализации протоколов, мы можем предоставить им интерфейс, который просто работает.