Re[25]: Каких программ вам не хватает?
От: · Великобритания  
Дата: 11.04.25 12:24
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>·>Закрытые для кого? Закрытость — вещь относительная. На какие-то атрибуты у тебя есть привилегии, на какие-то нет. У других пользователей будет другой доступ к атрибутам.

S>Нет. Вот как раз предлагаемая вами модель чревата дырками и крайне тяжела в поддержке и верификации.
S>Я вам рассказываю практический замкнутый пример: нет никаких "привилегий на втрибуты". Есть два вида ресурсов. Доступ к каждому их них либо есть, либо нету.
Где есть два вида? В спеке?

S>·>Каким образом закрыт-то? Заклятие наложено что-ли? Субресурс возвращает джсон, как ты ресурсом гарантируешь отстутствие там какого-нибудь contragent.homeAddress?

S>Очень просто: contragent.homeAddress там нет вообще, вне зависимости от привилегий.
Как конкретно это гарантируется? Только не говори: "в API нету!". Не слыхал историй, когда какие-нибудь rest-endpoints случайно возвращали json с неожиданными полями. All tests passed, всё у всех работает.

S>·>Почему ты так решил? Ты так говоришь, что ресурс это какая-то охраняемая зона за колючей проволокой.

S>Потому что я так спроектировал, и это легко проверить как методом "белого ящика", так и "чёрного ящика".
Ну о чём и говорю. "Спроектировал" — это написал тонну word-документов и презентаций. И проверить легко, не спорю. А на самом деле json генерится питонячим кодом, который рефлексией вываливает всё что есть. И даже если всё было красиво в начале проекта, то после нескольких лет поддержки, рефакторингов и переписывания вдруг может что-то где-то вылезти.

S>·>Нет, это просто несколько байт в определённом месте хедера запроса, а обрабатывает всё это дело тот же самый условно питонячий код, что и для других ресурсов.

S>Если у вас так, то всё плохо. Попробуйте перепроектировать так, чтобы в одном коде не смешивалась обработка "своих" и "чужих" инвойсов. Человечество изобрело массу способов факторизации кода.
Может такое только в каких-то мелких проектах и пройдёт... И то никакой гарантии, что кто-то куда-то по ошибке не скопипастит. В серьёзных случаях у тебя будет 1024 вида своих и чужих.

S>·>А чё так мелко? Сразу уж говори — источник данных — заряд на затворе транзистора. Да, там с привилегиями как-то не очень. Я вообще-то говорил о дизайне самого сервиса. БД — это уже другой сервис.

S>Нет, БД — это не "другой сервис", это неотъемлемый компонент сервиса, оборудованного персистентным состоянием.
Надо технически смотреть, а не по поверпоинт презентациям. БД — компонент, если embedded, в лучшем случае. А так по сути другой сервис — формируешь запрос (query) и получаешь ответ (recordset). Ничем по факту от какого-нибудь rest не отличается, только протокол общения другой, вместо http у тебя sql.

S>Впрочем, можно спроектировать и так, как вы предлагаете — вынести БД в отдельный сервис, из которого торчит очень широкий контракт.

S>И, естественно, у него очень грубый набор привилегий. Ваша модель "давайте мы будем ограничивать доступ путём передачи пользовательского токена вдоль всей иерархии вызовов" работает примерно никогда.
Что значит "вынести"? Попробуй хоть как-нибудь не "вынести" какой-нибудь оракл из твоего питоячего сервиса.

S>Все практики безопасности как раз так и устроены, что у принципала X нету привилегий к "сырому" ресурсу A, но есть привилегии на доступ к "производному" ресурсу B. Сервис, выполняющий построение ресурса B, выполняется под принципалом Y, который имеет полные привилегии для A, но учитывает привилегии X при отдаче ему производного ресурса B.

S>Типичный пример применения концепции в рамках SQL99: пользователю нельзя видеть часть строк в таблице X. Мы не можем навесить привилегию на каждую строку. Зато можем сделать следующее:
S>1. Отбираем у пользователя привилегии на таблицу X
S>2. Строим на основе X представление Y, в котором добавлен предикат безопасности (типа select * from X where TotalAmount < 100000)
S>3. Выдаём пользователю привилегии на Y и указываем, что Y исполняется под привилегиями админа, а не пользователя.
S>Аналогично мы могли бы поступить и с ограничениями на колонки таблицы. Квадратно-гнездовая система, где чётко видна вся схема Y и легко проверить, что туда попадает, а что нет, как методом статического анализа, так и методом выполнения динамических тестов. Вы предлагаете заменить её на некий невнятный код "хранимой процедуры", которая возвращает всякий раз разный набор строк и колонок в зависимости от рантайм-содержимого параметров.
Я как-то более о практике. Статический анализ, конечно, хорошо... Но если тебе для этого придётся описывать "1024 виртуальных ресурсов" и писать 2048 тестов для них, но это не заработает на практике, хотя в теории, конечно, красота...

S>Нет, увы. Факторизация кода позволяет нам изолировать разные сценарии.

Если у тебя два сценария, то, конечно, это щастье. А вот когда сценариев 1024...

S>·>А, так да. Но собственно тут обсуждалось "Безопасность очень часто входит в конфликт с производительностью", мой вопрос был "Интересно узнать какой такой магией фрагмент в урле повышает безопасность?". И в качестве ответа ты внезапно рассказываешь о "поднимает производительность" "не противоречит безопасности".

S>Фрагмент в урле существует не сам по себе. Структура урла применятся для роутинга — выбора кода, который будет обслуживать поступивший запрос. Правила роутинга — простая, понятная логика, которую легко отладить и гарантировать отсутствие неожиданностей вроде "в ответ на запрос чужих инвойсов внезапно вызвался код по подготовке своих инвойсов".
S>Следующим шагом мы можем очень легко проверить, что код по подготовке "чужих" инвойсов никогда не возвращает приватных данных. Просто потому, что в этом коде вообще нет такой ветки, которая бы это делала.
Ну будет у тебя 1024 кусков кода и неподдерживаемая кодовая база.

S>В вашем же подходе в коде какая-то каша, отдаётся примерно произвольный набор атрибутов с соответствии с хитро устроенными предикатами, смешивающими проверку нескольких разных claims. Доказать, что код выдаёт корректное сочетание атрибутов для произвольного сочетания claims — та ещё задача.

У меня проверка конкретного claim одна же. Я писал выше. Будет что-то
Json getInvoiceForRest(..., securityContext, ...) {
  verifyPrivilegesForTheInvoice(..., securityContext, ...);//тут мы проверяем привилегии для данного инвойса
  return new Invoice {
    date: getInvoiceDate(...)
    contragent: getContragentDetails(..., securityContext, ...)// вот внутри этого метода и проверятся имеющиеся привилегии и вернутся только доступные данные конртагента.
    shipping: getShippingDetails(..., securityContext, ...)// вот внутри этого метода и проверятся имеющиеся привилегии и вернутся только доступные данные о доставке.
  }
}

Конечно, это не отменяет "Правила роутинга" и другие подобные подходы, а дополняет. Как тут Miroff швейцарский сыр упоминал.

S>·>С чего ты взял? Никогда не было. А вот у тебя иллюзия в полный рост, цитирую: "чтобы границы безопасности совпадали с границами ресурсов. Потому что это и надёжнее,", "Зато всё безопасно". Нет, конечно. Надёжность тут не причём. Так просто удобнее и понятнее для человеков: не видно, что не должно быть видно. Т.е. чисто иллюзорные результаты.

S>Это оттого, что я плохо объясняю. Разница в подходах есть. Понятно, что достичь приемлемого результата можно в любом подходе, но стоимость получается разной. Когда границы безопасности совпадают с границами ресурсов, это сильно упрощает доказательство корректности. Я выше примерно написал, каким именно способом. Но вы можете мне не верить и писать более дорогостоящие и трудноподдерживаемые системы — у нас же нет архитектурной полиции
Ну я просто написал когда этот твой способ не работает. Но я, конечно, верю, что в некоторых случаях и твой способ работает. Но это не значит, что он универсальный всемогутер.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.