Команда Spring АйО перевела статью о том, как правильно настраивать безопасность на MCP серверах с использованием возможностей OAuth2 в свете новейшей спецификации MCP, вышедшей в свет 26-го марта 2025-го года, то есть совсем недавно.
Spring AI предлагает поддержку для Model Context Protocol или, сокращенно, MCP, что позволяет ИИ моделям взаимодействовать и получать доступ к внешним инструментам и ресурсам структурированно. С помощью Spring AI разработчики могут создавать свои собственные MCP сервера и давать ИИ моделям доступ к их возможностям всего в несколько строчек кода.
Авторизация и безопасность в MCP
MCP сервера могут работать локально, используя передачу по STDIO. Чтобы сделать MCP сервер доступным для внешнего мира, он должен предоставлять несколько стандартных HTTP эндпоинтов. В то время как MCP сервера, используемые локально и с целями тестирования, могут не требовать строгой аутентификации, продакшен деплойменты нуждаются в строжайшей безопасности и эффективном управлении permission-ами для доступных внешнему миру эндпоинтов. Эта проблема была решена в последней версии спецификации MCP (от 26-го марта 2025), которую выпустили на прошлой неделе. Она закладывает фундамент для безопасных коммуникаций между клиентами и серверами с использованием популярного протокола OAuth2.
Мы не собираемся делать полный обзор OAuth2 в рамках этой статьи, но немного освежить наши знания о нем будет полезно. В черновике спецификации MCP сервер описывается как одновременно и сервер ресурсов (он же OAuth2 Resource Server), и сервер авторизации (он же OAuth2 Authorization Server).
Будучи сервером ресурсов он выполняет проверки для авторизации входящих запросов, проверяя заголовок Authorization
. Заголовок должен содержать OAuth2 access_token
, который представляет из себя строку, описывающую “разрешения” (permissions-ы) клиента. Этот токен может быть JSON Web Token (JWT) или opaque token, который сам по себе не несет никакой информации. Если токен отсутствует или невалиден, (неправильно сформирован, истек, неверный получатель и т.д.), MCP сервер, будучи сервером ресурсов, отклоняет запрос. При использовании таких токенов типичный запрос может выглядеть вот так:
curl https://mcp.example.com/sse
-H "Authorization: Bearer <a valid access token>"
В качестве сервера авторизации, MCP сервер должен также обладать способностью выпускать access_token
`ы для клиентов безопасным образом. Прежде чем выпустить токен, сервер должен проверить креды клиента и, в некоторых случаях, identity клиента, который пытается получить доступ к серверу. Сервер авторизации принимает решения по характеристикам токена, таким как дата его истечения, scope-ы и т.д.
Используя Spring Security и Spring Authorization Server, мы можем легко добавить обе эти возможности к существующему Spring MCP серверу.

Добавление OAuth2 к вашему Spring MCP серверу
В приведенном примере мы добавим поддержку OAuth 2 к тестовому MCP серверу, который предоставляет дополнительные "погодные" данные (температура, влажность и т.д.) для LLM. Исходные коды MCP сервера можно найти в репозитории с примерами для Spring AI. Мы не будем заострять внимание на действиях клиентской стороны, только убедимся в том, что наш сервер может выпускать токены и валидировать их.
Прежде всего, импортируем необходимые нам Boot стартеры в pom.xml
:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-authorization-server</artifactId>
</dependency>
Далее, сконфигурируем OAuth2 клиент в нашем файле application.properties
, чтобы мы могли запрашивать токены доступа:
spring.security.oauth2.authorizationserver.client.oidc-client.registration.client-id=mcp-client
spring.security.oauth2.authorizationserver.client.oidc-client.registration.client-secret={noop}secret
spring.security.oauth2.authorizationserver.client.oidc-client.registration.client-authentication-methods=client_secret_basic
spring.security.oauth2.authorizationserver.client.oidc-client.registration.authorization-grant-types=client_credentials
Это самый простой из возможных клиентов. Мы можем взаимодействовать с сервером авторизации напрямую через POST запросы, браузер не нужен, и мы будем использовать прописанные в коде логин и пароль mcp-client / secret
.
Последний шаг — включить использование возможностей авторизационного сервера и сервера ресурсов. Мы сделаем это, создав конфигурационный класс для возможностей по безопасности, например, SecurityConfiguration
, в котором мы дадим доступ к бину SecurityFilterChain
:
import static org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer.authorizationServer;
@Configuration
@EnableWebSecurity
class SecurityConfiguration {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http.authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
.with(authorizationServer(), Customizer.withDefaults())
.oauth2ResourceServer(resource -> resource.jwt(Customizer.withDefaults()))
.csrf(CsrfConfigurer::disable)
.cors(Customizer.withDefaults())
.build();
}
}
Эта цепочка фильтров сделает несколько вещей:
Гарантирует, что каждый запрос аутентифицируется. Благодаря этому, наш MCP сервер будет разрешать только запросы с
access_token
.Разрешает использование как Spring Authorization Server, так и Spring Resource Server.
Отключает CSRF (Cross-Site Request Forgery). MCP сервер не предназначен для взаимодействия с браузерами, поэтому CSRF-защита здесь не нужна.
Включает поддержку CORS (Cross-Origin Resource Sharing), чтобы мы могли продемонстрировать сервер при помощи MCP инспектора.
Эти действия обеспечивают безопасность нашему приложению, которое теперь будет принимать только те запросы, в которых есть токен доступа. В противном случае запросы будут отклонены с ошибкой HTTP 401 Unauthorized
. Например:
curl http://localhost:8080/sse --fail-with-body
#
# Response:
#
# curl: (22) The requested URL returned error: 401
Чтобы использовать наш MCP сервер, нам сперва необходимо получить токен доступа. Мы используем client_credentials
, выданные OAuth2, что используется в сценариях “от машины к машине” или “сервисный аккаунт”:
curl -XPOST http://localhost:8080/oauth2/token --data grant_type=client_credentials --user mcp-client:secret
#
# Response:
#
# {"access_token":"<YOUR-ACCESS-TOKEN>","token_type":"Bearer","expires_in":299}%
Копируем значение access_token
. Оно начинается с букв "ey". Теперь мы можем использовать этот токен для создания запросов, и они должны быть успешными. Например, используя curl
, вы сможете заменить YOUR_ACCESS_TOKEN
скопированным выше значением:
curl http://localhost:8080/sse -H"Authorization: Bearer YOUR_ACCESS_TOKEN"
#
# Response:
#
# id:918d5ebe-9ae5-4b04-aae8-c1ff8cdbb6e0
# event:endpoint
# data:/mcp/message?sessionId=918d5ebe-9ae5-4b04-aae8-c1ff8cdbb6e0
Можно также использовать токен доступа напрямую в MCP инспекторе, начиная с версии 0.6.0
. Просто запустите инспектор и вставьте токен доступа в поле "Authentication > Bearer" в меню слева. Затем нажмите “Connect”: теперь у вас должна появиться возможность отправлять MCP вызовы.

Если вы хотите запустить эти программы самостоятельно, вы можете взять код примера из репозитория spring-ai-examples
.
Что дальше?
В нашем примере мы реализовали базовые возможности OAuth2 в MCP сервере.
Очевидный следующий шаг — обновить MCP клиент и позволить ему аутентифицироваться на сервере с использованием OAuth2 authorization_code
grant-а вместо client_credentials
. При таком сценарии пользователи смогут залогиниться со своими собственными кредами и получить свои пользовательские токены, что позволяет более точно назначать пермишены, например с помощью Roles-Based Access Control (RBAC).
В будущем, мы также посмотрим на внешний сервер авторизации OAuth2 и выпуск токенов с его помощью, используя только возможности сервера ресурсов (OAuth2 Resource Server-а) внутри нашего MCP сервера.

Присоединяйтесь к русскоязычному сообществу разработчиков на Spring Boot в телеграм — Spring АйО, чтобы быть в курсе последних новостей из мира разработки на Spring Boot и всего, что с ним связано.