Практичні поради: Рецепт Spring AI: Забезпечення безпеки сервера MCP за допомогою OAuth
Покрокове керівництво з практичних нотаток: Spring AI Recipe: Забезпечення безпеки сервера MCP за допомогою OAuth: контракти, перевірки та готові фрагменти коду для команд, які використовують цю схему.
Наведені нижче примітки описують практичний підхід до реалізації проекту «Spring AI Recipe: Забезпечення безпеки сервера MCP за допомогою OAuth». Основна увага приділяється контрактам, перевіркам та шаблонам коду, а не мотиваційним аспектам. Під час етапу огляду спочатку запишіть контракт: необхідні вхідні дані, сигнал про успіх та наслідки часткової невдачі. Такий перелік допоможе зберегти чесність у подальших змінах коду. Тримайте конфігурацію окремо від коду додатку. Файли середовища, сховища секретів та флаги функцій мають знаходитися в одному місці, яке оператори можуть перевіряти, не читаючи весь код.
Створення сервера авторизації
Етап створення сервера авторизації працює найкраще, якщо його розглядати як вимірювану поверхню. Зафіксуйте один ідеальний варіант роботи, один випадок збою та примітки щодо скасування змін перед розширенням обсягу функцій. Документуйте як успішний, так і відновлювальний сценарії роботи. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої оптимізації. Зробіть інструменти доступними з вузькими схемами та чіткими позначеннями побічних ефектів. Хостам потрібно знати, які виклики змінюють стан системи, перш ніж вони автоматично схвалюють їх.
implementation 'org.springaicommunity:mcp-authorization-server:0.1.14'
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth ->
auth.anyRequest().authenticated())
.formLogin(withDefaults())
.with(
McpAuthorizationServerConfigurer.mcpAuthorizationServer(),
withDefaults())
.build();
}
}
spring:
application:
name: recipes-authorization-server
security:
oauth2:
authorizationserver:
client:
default-client:
token:
access-token-time-to-live: 1h
registration:
client-id: "myclient"
client-secret: "{noop}mysecret"
client-authentication-methods:
- "client_secret_basic"
authorization-grant-types:
- "authorization_code"
redirect-uris:
- "http://localhost:6274/oauth/callback"
- "http://127.0.0.1:6274/oauth/callback"
scopes:
- general-access
- meteorology
- administration
user:
name: craig
password: letmein
server:
port: 9999
Забезпечення безпеки сервера MCP
Етап забезпечення безпеки сервера MCP найкраще функціонує, якщо його розглядати як вимірювану поверхню. Збережіть один ідеальний запис діяльності, один випадок збою та примітку про скасування змін перед розширенням обсягу роботи. Віддавайте перевагу невеликим, тестованим одиницям перед складними скриптами. Коли якийсь крок зазнає невдачі, причина має вказувати на конкретну відповідальність, а не на заплутану послідовність дій. Використовуйте інструменти з вузькими схемами та чіткими позначеннями побічних ефектів. Хостам потрібно знати, які виклики змінюють стан, перш ніж вони автоматично схвалять їх.
implementation 'org.springaicommunity:mcp-server-security:0.1.14'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:9999
@Configuration
@EnableWebSecurity
class McpSecurityConfig {
@Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
private String issuerUrl;
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth ->
auth.anyRequest().authenticated())
.with(
McpServerOAuth2Configurer.mcpServerOAuth2(),
(mcpAuthorization) -> {
mcpAuthorization.authorizationServer(issuerUrl);
}
)
.build();
}
}
Тестування сервера MCP
Етап тестування сервера MCP працює найкраще, коли його розглядають як вимірювану поверхню. Збережіть один ідеальний запис, один випадок збою та примітку про скасування змін перед розширенням обсягу роботи. Розглядайте цей етап як контракт між вхідними даними та перевіреними результатами. Позначте всі елементи, визначте критерії успіху та не допускайте мовчазного часткового виконання завдань. Використовуйте інструменти з вузькими схемами та чіткими позначеннями побічних ефектів. Адміністраторам потрібно знати, які виклики змінюють стан системи, перш ніж автоматично схвалювати їх. Етап тестування сервера MCP працює найкраще, коли його розглядають як вимірювану поверхню. Збережіть один ідеальний запис, один випадок збою та примітку про скасування змін перед розширенням обсягу роботи. Зберігайте конфігурацію окремо від коду програми. Файли середовища, сховища конфіденційних даних та флаги функцій мають знаходитися в одному місці, де оператори можуть їх перевіряти, не читаючи весь код.
Забезпечення безпеки окремих інструментів
На етапі забезпечення безпеки окремих інструментів необхідно визначити вхідні дані, власника кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись вгадати прихований стан.
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
class SecurityConfig {
@Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
private String issuerUrl;
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> {
auth.requestMatchers("/mcp").permitAll();
auth.anyRequest().authenticated();
})
.with(
McpServerOAuth2Configurer.mcpServerOAuth2(),
(mcpAuthorization) -> {
mcpAuthorization.authorizationServer(issuerUrl);
}
)
.build();
}
}
@PreAuthorize("hasAuthority('SCOPE_meteorology')")
@McpTool(
name = "get-weather-for-zipcode",
description = "Gets the weather for a given zipcode",
annotations = @McpTool.McpAnnotations(
openWorldHint = false,
destructiveHint = false,
idempotentHint = true))
Weather getWeatherForZipcode(
@McpToolParam(description = "The zipcode to get weather for")
String zipcode) {
var context = SecurityContextHolder.getContext();
var username = context.getAuthentication().getName();
return new Weather(
zipcode,
"Raining cats and dogs",
78.0f,
username);
}
Чек-лист для експлуатації
На етапі чек-листу для експлуатації також потрібно визначити вхідні дані, власника кроку та критерії завершення перед зміною коду. Оператори мають можливість перезапустити крок з відомої точки контролю без необхідності вгадування прихованих даних.
Записуйте час виконання та витрати на токени чи запити поруч із функціональними результатами. Візуалізація витрат на ранньому етапі запобігає несподіваним рахункам під час переходу з демо-середовища у спільні.
Аутентифікуйтеся біля шлюзу та повторно авторизуйтеся на рівні обробки даних. Один лише токен-носій не є межею окремого тенантства.
Напишіть короткий посібник: як оновлювати ключі, як спорожнювати чергу, як скасовувати останнє завантаження даних.
Зберігайте конфігурацію окремо від коду додатку. Файли середовищ, сховища секретів та флаги функцій мають знаходитися в одному місці, де оператори можуть їх перевіряти, не читаючи весь граф.
Аутентифікуйтеся біля шлюзу та повторно авторизуйтеся на рівні обробки даних. Один лише токен-носій не є межею окремого тенантства.
Перш ніж запускати стек у продакшн, заморозьте версії, створіть «золотий» запис для критичного шляху та підтвердьте кроки відкату. У спільних середовищах необхідні обмеження на частоту використання, перевірки прав доступу та чіткий власник для зміни секретів. Віддавайте перевагу надійності перед креативними одноразовими демонстраціями.
Примітка до пакету 01496ca9e17e: не зберігайте ключі постачальника у репозиторії, встановіть ліміт токенів на сеанс та зберігайте записи поруч із фікстурами для оцінки, щоб подальша заміна моделей залишалася порівнянною.
Для етапу 0 щодо посилення безпеки визначте вхідні дані, власника кроку та критерії завершення ще до зміни коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не здогадуючись про прихований стан. Розглядайте цей етап як контракт між вхідними даними та перевіреними результатами. Позначте артефакти, визначте критерії успіху та не допускайте мовчазного часткового завершення.
Деталь посилення безпеки 0/819: виміряйте час виконання, клас помилки та кількість витрачених токенів для цього запису, а потім вирішіть, чи залишити зміни, ґрунтуючись на фіксованому наборі питань, а не на окремих випадках.
Під час роботи над першим етапом запису про посилення безпеки спочатку запишіть контракт: необхідні вхідні дані, сигнал про успіх та те, що відбувається при частковій невдачі. Цей перелік допомагає зберігати чесність подальших змін у коді. Зберігайте конфігурацію окремо від коду додатку. Файли середовища, сховища секретів та флаги функцій мають знаходитися в одному місці, де оператори можуть їх перевіряти, не читаючи весь код.
Деталь посилення безпеки 1/819: виміряйте час виконання, клас помилки та кількість витрачених токенів для цього запису, а потім вирішіть, чи залишити зміни, ґрунтуючись на фіксованому наборі питань, а не на окремих випадках.
Етап 2 процедури посилення безпеки працює найкраще, якщо його розглядати як вимірювану поверхню. Збережіть один ідеальний зразок виконання, один випадок збою та запис про скасування змін перед розширенням обсягу роботи. Віддавайте перевагу невеликим, тестованим одиницям перед складними скриптами. Коли якийсь крок зазнає невдачі, причина має вказувати на конкретну відповідальність, а не на заплутану послідовність дій.
Деталь посилення безпеки 2/819: виміряйте час виконання, клас помилки та кількість витрачених ресурсів для цього запису, а потім вирішіть, чи залишити зміни, ґрунтуючись на фіксованому наборі питань, а не на окремих прикладах.
Для третьої стадії процедури зміцнення необхідно визначити вхідні дані, відповідальну особу за кожен крок та критерії завершення перед зміною коду. Оператори мають мати можливість перезапустити крок з відомої точки контролю, не намагаючись визначити прихований стан системи. Необхідно фіксувати час виконання та витрати на токени чи запити поруч із функціональними результатами. Чітке бачення витрат заздалегідь запобігає несподіваним рахункам під час переходу з демо-середовища у спільні середовища.
Деталь зміцнення 3/819: вимірюйте час виконання, клас помилок та витрати на токени для цієї процедури, а потім вирішуйте, чи залишити зміни, ґрунтуючись на фіксованому наборі критеріїв, а не на індивідуальних спостереженнях.
Під час виконання 4-го етапу додаткових заходів зпрочнення спочатку запишіть умови контракту: необхідні вхідні дані, сигнал про успіх та те, що відбувається у разі часткової невдачі. Цей перелік допомагає зберігати чесність пізніших змін у коді. Документуйте як шлях успішної роботи, так і шлях відновлення одночасно. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої доробки.
Деталі заходу зпрочнення 4/819: вимірюйте час виконання, клас помилки та кількість витрачених токенів для цього етапу, а потім вирішуйте, чи залишити зміни, ґрунтуючись на фіксованому наборі критеріїв, а не на окремих випадках.
4-й етап додаткових заходів зпрочнення працює найкраще, якщо його розглядати як вимірювану поверхню. Збережіть один ідеальний запис виконання, один випадок невдачі та запис про скасування змін перед розширенням обсягу роботи. Розглядайте цей етап як контракт між вхідними даними та перевіреними результатами. Позначте всі елементи, визначте критерії успіху та не допускайте мовчазного часткового завершення роботи.
Деталь посилення безпеки 5/819: виміряйте час виконання, клас помилки та кількість витрачених токенів для цього запису, а потім вирішіть, чи залишити зміни, ґрунтуючись на фіксованому наборі питань, а не на окремих випадках.
На 6-му етапі роботи над посиленням безпеки необхідно визначити вхідні дані, відповідальну особу та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити цей етап з відомої точки контролю, не здогадуючись про прихований стан. Зберігайте конфігурацію окремо від коду додатку. Файли середовища, сховища конфіденційних даних та флаги функцій мають знаходитися в одному місці, яке оператори можуть перевіряти, не читаючи весь код.
Деталь посилення безпеки 6/819: виміряйте час виконання, клас помилки та кількість витрачених токенів для цього запису, а потім вирішіть, чи залишити зміни, ґрунтуючись на фіксованому наборі питань, а не на окремих випадках.