Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Java Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2 3 4 5 6 7   вперед  Ctrl      все
 Spring Security имеет неверную архитектуру  [new]
dakeiras
Member

Откуда:
Сообщений: 445
Привет хабр!

Для всех тех кто свято верит в авторитет массы, вот пример когда такой массовый (а следовательно авторитетный) фреймворк имеет модуль с концептуально неверной архитектурой.

Итак - Spring Security.

В нём мы определям правила доступа на уровне ресурса. Это противоречит здравому смыслу: откуда конкретному ресурсу знать кому разрешено им пользоваться?

Пример ресурса: товар в магазине. Товар не знает какую цену за него назначил магазин. И не может сам себе проверить цену.

Как должно быть правильно (а не как в Spring Security)?
- Цену проверяет кассир по ценнику, и он же определяет достаточно ли денег у покупателя на данный товар

Подход в Spring Security вызывает целую массу явных и неявных проблем:
- Платформозависимость (работает только с ресурсами реализованными в Spring)
- Правила доступа захардкожены в коде (это просто пипец, дожили)
- Децентрализация правил авторизации - правила аутентификации настраиваются отдельно от правил доступа (и возможно разными людьми в разных серверах)
- Сама сущность User Role противоречит естественной объектной модели - по факту это как делать доп. поле "type" в каком-то классе: получается декларативный полиморфизм. Правильно было бы выделять каждую отдельную роль в свой класс (например User, Admin) - потому что Роль - это поведение объекта, а не его данные.
- Токены проверяются ресурсном сервере, что нагружает его и базу (особенно в случае хакерских атак)

В результате имеем следующее:
- Authorization хедер по факту является аутентификационным
- Все REST API становятся stateful из-за этого (берётся роль юзера из базы каждый раз) - что противоречит само себе
- Полный хаос в терминологии и реализации - а значит риск потенциальных уязвимостей
- Техническая отсталость функциональности контроля доступа
- Фактическое отсутствие общепринятных решений для Step-up авторизации

Выводы:
1) Не надо доверять авторитету массы
2) Концепции заложенные в WWW ещё далеки от технологически совершенной реализации на практике

Ваши мысли?

PS: я тут уже сделал платформонезависимый протокол авторизации который всё это исправляет. Кому интересно:
https://github.com/INFINITE-TECHNOLOGY/ASCEND
(технически доделано на 100%, но документации нет - и возвожно и не будет никогда, т.к. никому это походу не интересно, а сил и времени не хватает)
12 май 20, 08:41    [22130932]     Ответить | Цитировать Сообщить модератору
 Re: Spring Security имеет неверную архитектуру  [new]
dakeiras
Member

Откуда:
Сообщений: 445
Вот так например выглядит Ascend JWT:

{
  "guid" : "0edbbc78-5b39-4ac1-be87-0db95943db8f",
  "name" : "registeredUserScopeAuthorization",
  "serverNamespace" : "OrbitSaaS",
  "clientNamespace" : "672032854",
  "identity" : {
    "name" : "registeredUser",
    "authentications" : [ {
      "name" : "user",
      "privateCredentials" : { }
    } ],
    "publicCredentials" : { }
  },
  "scope" : {
    "name" : "registeredUserScope",
    "grants" : [ {
      "urlRegex" : "https:\\/\\/orbit-secured\\.herokuapp\\.com\\/orbit\\/secured\\/user\\/%userGuid%\\/.*",
      "bodyRegex" : null,
      "httpMethod" : "POST"
    }, {
      "urlRegex" : "https:\\/\\/orbit-secured\\.herokuapp\\.com\\/orbit\\/secured\\/user\\/%userGuid%\\/.*",
      "bodyRegex" : null,
      "httpMethod" : "GET"
    } ]
  },
  "durationSeconds" : 300,
  "maxUsageCount" : null,
  "creationDate" : "2020-05-12T03:08:13.646",
  "expiryDate" : "2020-05-12T03:13:13.646",
  "jwt" : "eyJhbG....",
  "prerequisite" : null,
  "refresh" : null,
  "authorizedCredentials" : {
    "phone" : "971559307088",
    "userGuid" : "8085acd2-0f96-49fc-8996-d047b09f0818"
  }
}


Тут и в явном виде ресурсы разрешённые, и поле prerequisite для step up, и поле refresh, и приципалы в структурированном виде...
Это нормальный формат. А не то, что нам предлагает OAuth2.

Там вообще отбито напрочь, expiry date это "claim". CLAIM, Карл!!! У того кто это придумывал явно были нелады с Англ. языком, потому что ни в одном из значений слова Claim, оно не подходит по смыслу того как его используют в OAuth2. И тоже самое с другой терминологией там...
12 май 20, 08:49    [22130940]     Ответить | Цитировать Сообщить модератору
 Re: Spring Security имеет неверную архитектуру  [new]
dakeiras
Member

Откуда:
Сообщений: 445
Ну и чтобы добить, всё это stateless и поддерживает discoverability.

Просто перейдите по ссылке:
https://ascend-secaas.herokuapp.com/ascend/public/granting/inquire?scopeName=registeredUserScope&serverNamespace=OrbitSaaS

Чтобы узнать как нужно юзеру авторизоваться, чтобы получить доступ к scope "registeredUserScope" на сервере ресурсов "OrbitSaas".

Ссылка выше рабочая, смелее - нажмите. Там интересно :)

Сообщение было отредактировано: 12 май 20, 08:52
12 май 20, 08:52    [22130942]     Ответить | Цитировать Сообщить модератору
 Re: Spring Security имеет неверную архитектуру  [new]
mayton
Member

Откуда: loopback
Сообщений: 46531
dakeiras

В нём мы определям правила доступа на уровне ресурса. Это противоречит здравому смыслу: откуда конкретному ресурсу знать кому разрешено им пользоваться?

Пример ресурса: товар в магазине. Товар не знает какую цену за него назначил магазин. И не может сам себе проверить цену.

Вот с этого момента сразу непонятно. При чем здесь Spring Security и товар. Очевидно что автор
пропустил целый слой абстракций и сразу прыгнул в предметную область. Это странно и для
читающих совершенно неочевидно. Это - твоя предметная область. И бизнес устанавливает
на нее свои правила. И если у тебя сыр знает сколько он стоит - то значит это выгодно
для бизнеса и это ничего не нарушает. А если ты не смог SpringSec абстракции притянуть
к этому умному сыру то скорее всего тебе либо SpringSec не нужен либо ты чего-то сам
неверно спроектировал.

В инфо-безопасности есть принцип Role-Based-Control
когда следующий сет рулов управляет объектными привилениями всей системы.
Типа

{ role1, permission1, subject1 }
{ role2, permission2, subject2 }
...


Есть еще развитие с сессиями и т.д и есть бумажные версии этого стандарта которые детализируют этот куб свойств.
12 май 20, 10:59    [22131017]     Ответить | Цитировать Сообщить модератору
 Re: Spring Security имеет неверную архитектуру  [new]
mayton
Member

Откуда: loopback
Сообщений: 46531
dakeiras

- Децентрализация правил авторизации - правила аутентификации настраиваются отдельно от правил доступа (и возможно разными людьми в разных серверах)

Это нормально. Так и работают современные системы. Яркий пример - многофакторная аутентификация проверяет
кто - ты. И назначает тебе токен (или тикет). Далее ты ходишь с этим токеном и заходишь в разные интерфейсы
и интерфейсы уже зная тебя и твою роль в токене авторизуют - проверяют можешь ли ты делать какое-то действие.

Или еще пример. Ты приехал на конференцию. Прошел в здание через проходную. Офицер тебя проверил и выдал
бейджик на котором написано "dakeiras/member". Аутентификация. Далее ты поднимаешься в конферец-холл и следующий офицер
проверяет что ты участник конфы (докладчик) и пропускает тебя в рум для докладчиков. Это авторизация. Ты
авторизован чтобы докладывать.
12 май 20, 11:04    [22131020]     Ответить | Цитировать Сообщить модератору
 Re: Spring Security имеет неверную архитектуру  [new]
mayton
Member

Откуда: loopback
Сообщений: 46531
dakeiras

- Правила доступа захардкожены в коде (это просто пипец, дожили)

Тем хардкода в Spring - это отдельная и сложная тема. И можно топик создавать.
Но если у тебя рулы безопасности определены через роли - то такой хардкод
я-бы одобрил.

Тоесть если сыр входит в роль "price-readers" тогда правило разрешения
может выглядеть так.

{ price-readers, read, price }


И такой role-based-access-contol (RBAC) можно спокойно хардкодить в код.
Он не будет меняться десятки лет. Или если изменится то только с изменениями
самого кода. Что само по себе нормально.
12 май 20, 11:10    [22131023]     Ответить | Цитировать Сообщить модератору
 Re: Spring Security имеет неверную архитектуру  [new]
mayton
Member

Откуда: loopback
Сообщений: 46531
dakeiras

- Все REST API становятся stateful из-за этого (берётся роль юзера из базы каждый раз) - что противоречит само себе

Если рассматривать хедеры Rest и сам смысл Request отдельно то никакого противоречия нет.
Если ты правильно проектировал Rest API как stateless то он таковым и остался.
12 май 20, 11:25    [22131039]     Ответить | Цитировать Сообщить модератору
 Re: Spring Security имеет неверную архитектуру  [new]
SpringMan
Member

Откуда:
Сообщений: 166
Мне кажется ТС плохо читал документацию. Spring Security вполне может работать c jwt (к примеру keycloak). Если его мало, то вполне можно реализовать свой spring-security-провайдер, который будет работать с твоим токеном. Плюс даже без завязки на базу данных/хардкод чего-либо в коде/без обращений на сервер авторизации и всех этих страшных вещей
P.S. не особо понял, что в твоем jwt-токене такого особенного, чтобы к примеру такую же функциональность нельзя было бы реализовать в keycloak или т.п. ?

Сообщение было отредактировано: 12 май 20, 12:44
12 май 20, 12:37    [22131094]     Ответить | Цитировать Сообщить модератору
 Re: Spring Security имеет неверную архитектуру  [new]
mayton
Member

Откуда: loopback
Сообщений: 46531
Я не вижу в сорцах чтобы автор использовал аннотации @Secured, @RolesAllowed.
12 май 20, 12:59    [22131114]     Ответить | Цитировать Сообщить модератору
 Re: Spring Security имеет неверную архитектуру  [new]
SpringMan
Member

Откуда:
Сообщений: 166
Ну пока вообще не ясно, что есть кроме токена. Как с этим должен работать человек, который захочет прикрутить эту штуку себе?
12 май 20, 13:05    [22131122]     Ответить | Цитировать Сообщить модератору
 Re: Spring Security имеет неверную архитектуру  [new]
mayton
Member

Откуда: loopback
Сообщений: 46531
Непонянто. Автору я предлагаю добавить в README.md краткий пример на 5-10 строчек.
Как подключить в свой проект его штуку.
12 май 20, 13:08    [22131124]     Ответить | Цитировать Сообщить модератору
 Re: Spring Security имеет неверную архитектуру  [new]
dakeiras
Member

Откуда:
Сообщений: 445
всем спасибо за комментарии, на свежую голову отвечу сегодня чуть позже подробно.

По использованию - тоже покажу. Интерес есть, это оч. радует - значит буду делать документацию и рассказывать тут.

Из особенностей - в токене есть регулярные выражения для валидаци доступа к URL (с %подстановками%), т.е. токен самовалидируемый.
12 май 20, 13:21    [22131137]     Ответить | Цитировать Сообщить модератору
 Re: Spring Security имеет неверную архитектуру  [new]
mayton
Member

Откуда: loopback
Сообщений: 46531
Я кстати обнаружил вредноносный код у тебя.
12 май 20, 13:36    [22131156]     Ответить | Цитировать Сообщить модератору
 Re: Spring Security имеет неверную архитектуру  [new]
dakeiras
Member

Откуда:
Сообщений: 445
mayton
Я кстати обнаружил вредноносный код у тебя.


какой из: Class.forName или context.getBean? :)
12 май 20, 20:15    [22131526]     Ответить | Цитировать Сообщить модератору
 Re: Spring Security имеет неверную архитектуру  [new]
mayton
Member

Откуда: loopback
Сообщений: 46531
Вот этот. Надо срочно убрать из кода.

compile "io.i-t:bobbin:3.0.0"
12 май 20, 20:20    [22131530]     Ответить | Цитировать Сообщить модератору
 Re: Spring Security имеет неверную архитектуру  [new]
dakeiras
Member

Откуда:
Сообщений: 445
автор
И если у тебя сыр знает сколько он стоит - то значит это выгодно
для бизнеса и это ничего не нарушает.


Правильно пишете, с точки зрения традиционного понимания Web безопасности.
Но что мы тут предлагаем - поменять это понимимание: вынести безопасность в отдельный инфраструктурный слой, прозрачный для приложений. Т.е. то, как это и было задумано изначально при проектировании Веба (но к сожалению не было осилено до сих пор).

автор
Это нормально. Так и работают современные системы. Яркий пример - многофакторная аутентификация проверяет
кто - ты. И назначает тебе токен (или тикет). Далее ты ходишь с этим токеном и заходишь в разные интерфейсы
и интерфейсы уже зная тебя и твою роль в токене авторизуют - проверяют можешь ли ты делать какое-то действие.

Или еще пример. Ты приехал на конференцию. Прошел в здание через проходную. Офицер тебя проверил и выдал
бейджик на котором написано "dakeiras/member". Аутентификация. Далее ты поднимаешься в конферец-холл и следующий офицер
проверяет что ты участник конфы (докладчик) и пропускает тебя в рум для докладчиков. Это авторизация. Ты
авторизован чтобы докладывать.

Да, но и в реальном мире это уязвимость в JWT. Вот пример сценария из платёжного мира:

Как сделано в EMV (правильно):
1) Криптограмма (авторизационный токен) транзакции атомарна и содержит в себе аутентификационные данные (PVV или PIN Offset - проверочные значения ПИНа), и сумму покупки. При этом сумма показывается на терминале в момент ввода ПИНа.

Как это было бы сделано в JWT (неправильно):
1) Всё тоже самое, но Вы не видите для какой суммы Вы вводите ПИН. И эта информация (авторизационная) не включается в JWT токен (аутентификационный).
В итоге с Вас списывают больше денег чем нужно.

Сообщение было отредактировано: 12 май 20, 21:12
12 май 20, 21:13    [22131567]     Ответить | Цитировать Сообщить модератору
 Re: Spring Security имеет неверную архитектуру  [new]
dakeiras
Member

Откуда:
Сообщений: 445
del

Сообщение было отредактировано: 12 май 20, 21:12
12 май 20, 21:13    [22131569]     Ответить | Цитировать Сообщить модератору
 Re: Spring Security имеет неверную архитектуру  [new]
dakeiras
Member

Откуда:
Сообщений: 445
автор
Я не вижу в сорцах чтобы автор использовал аннотации @Secured, @RolesAllowed.


Потому что они как раз и замещаются. См. ниже ссылки.

автор
Если рассматривать хедеры Rest и сам смысл Request отдельно то никакого противоречия нет.
Если ты правильно проектировал Rest API как stateless то он таковым и остался.


В широком смысле: если используется контекст, это уже не Stateless. Роль пользователя в контексте хранится.
В общем, это неидеальная ситуация.
12 май 20, 21:22    [22131573]     Ответить | Цитировать Сообщить модератору
 Re: Spring Security имеет неверную архитектуру  [new]
dakeiras
Member

Откуда:
Сообщений: 445
автор
Мне кажется ТС плохо читал документацию. Spring Security вполне может работать c jwt (к примеру keycloak). Если его мало, то вполне можно реализовать свой spring-security-провайдер, который будет работать с твоим токеном. Плюс даже без завязки на базу данных/хардкод чего-либо в коде/без обращений на сервер авторизации и всех этих страшных вещей
P.S. не особо понял, что в твоем jwt-токене такого особенного, чтобы к примеру такую же функциональность нельзя было бы реализовать в keycloak или т.п. ?


И всё это остаётся узко связанным с кодом приложения.

автор
Ну пока вообще не ясно, что есть кроме токена. Как с этим должен работать человек, который захочет прикрутить эту штуку себе?

автор
Непонянто. Автору я предлагаю добавить в README.md краткий пример на 5-10 строчек.
Как подключить в свой проект его штуку.


Очень просто, и максимально отвязанно от самих приложений.

Клиентская часть (Ascend Granting Client Java SDK):
    @Autowired
    ClientAuthorizationGrantingService clientAuthorizationGrantingService
...
        HttpResponse httpResponse = clientAuthorizationGrantingService.sendAuthorizedHttpMessage(
                new AuthorizedHttpRequest(
                        url: "$orbitUrl/orbit/secured/user/${authorization.authorizedCredentials.get("userGuid")}/history",
                        method: "GET",
                        headers: [
                                "Content-Type" : "application/json",
                                "Accept"       : "application/json"
                        ],
                        scopeName: "registeredUserScope",
                        ascendUrl: ascendGrantingUrl,
                        authorizationClientNamespace: chatId.toString(),
                        authorizationServerNamespace: "OrbitSaaS"
                )
        )

Вот всё, что требуется. Такой код сделает следующее внутри:
1) Спросит у Авторизационного сервера, какие есть варианты для авторизации для scope "OrbitSaas"
2) Автоматически даст юзеру выбрать желаемый вариант аутентификации и авторизации (интерактивно)
3) Поищет в клиентском хранилище, есть ли уже такие активные (non-expired, not exceeded usage count) авторизации (или Refresh к ним)
4) Если нет - Соберёт данные для аутентификации (включая пользовательский ввод)
5) Пошлёт авторизационный запрос на Authorization Granting Server.
6) Получит авторизационный токен, сохранит его в пользовательское хранилище
7) Включит его в запрос к защищённому ресурсу (и увеличит счётчик использований в клиентском хранилище)

Сейчас делается клиентский SDK для JavaScript.

Сообщение было отредактировано: 12 май 20, 21:37
12 май 20, 21:37    [22131585]     Ответить | Цитировать Сообщить модератору
 Re: Spring Security имеет неверную архитектуру  [new]
dakeiras
Member

Откуда:
Сообщений: 445
На сервере (защищённом ресурсе):

https://github.com/INFINITE-TECHNOLOGY/ORBIT/tree/master/orbit-sdk/src/main/groovy/io/infinite/orbit/configurations/security

Т.е. фильтр:
package io.infinite.orbit.configurations.security

import groovy.util.logging.Slf4j
import io.infinite.ascend.validation.client.services.ClientAuthorizationValidationService
import io.infinite.blackbox.BlackBox
import io.infinite.carburetor.CarburetorLevel
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Service
import org.springframework.web.filter.OncePerRequestFilter

import javax.servlet.FilterChain
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

/**
 * https://github.com/OmarElGabry/microservices-spring-boot/blob/master/spring-eureka-zuul/src/main/java/com/eureka/zuul/security/JwtTokenAuthenticationFilter.java
 */

@Slf4j
@BlackBox(level = CarburetorLevel.METHOD)
@Service
class OrbitJwtTokenAuthenticationFilter extends OncePerRequestFilter {

    ClientAuthorizationValidationService clientAuthorizationValidationService = new ClientAuthorizationValidationService()

    @Value('${ascendValidationUrl}')
    String ascendValidationUrl

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {
        clientAuthorizationValidationService.validateServletRequest(ascendValidationUrl, request, response, filterChain)
    }

}


Но по факту это может быть платформонезависимый реверс прокси.
12 май 20, 21:43    [22131594]     Ответить | Цитировать Сообщить модератору
 Re: Spring Security имеет неверную архитектуру  [new]
dakeiras
Member

Откуда:
Сообщений: 445
И таких картинок много, документация готова на 70%. Не хватает времени добить :(

К сообщению приложен файл. Размер - 128Kb


Сообщение было отредактировано: 12 май 20, 21:58
12 май 20, 21:52    [22131606]     Ответить | Цитировать Сообщить модератору
 Re: Spring Security имеет неверную архитектуру  [new]
dakeiras
Member

Откуда:
Сообщений: 445
Сорри, sql.ru не даёт картинку изменить в редактировании сообщения.

К сообщению приложен файл. Размер - 147Kb
12 май 20, 22:00    [22131613]     Ответить | Цитировать Сообщить модератору
 Re: Spring Security имеет неверную архитектуру  [new]
SpringMan
Member

Откуда:
Сообщений: 166
dakeiras

И всё это остаётся узко связанным с кодом приложения.

Права довольно часто и есть часть логики приложения. Как быть с правами, которые даются пользователю не напрямую? К примеру: пользователь может видеть/редактировать все объекты у подчиненных ему других пользователей. Или на объекты из определенных регионов и т.п. Довольно много систем, которые не могут быть завязаны только на урлы

Сообщение было отредактировано: 12 май 20, 22:21
12 май 20, 22:21    [22131620]     Ответить | Цитировать Сообщить модератору
 Re: Spring Security имеет неверную архитектуру  [new]
mayton
Member

Откуда: loopback
Сообщений: 46531
dakeiras
автор
Я не вижу в сорцах чтобы автор использовал аннотации @Secured, @RolesAllowed.


Потому что они как раз и замещаются. См. ниже ссылки.

Где конкретнее смотреть? На что они замещаются?
12 май 20, 22:34    [22131630]     Ответить | Цитировать Сообщить модератору
 Re: Spring Security имеет неверную архитектуру  [new]
SpringMan
Member

Откуда:
Сообщений: 166
ТС имеет в виду, что все проверки замещаются одним фильтром OrbitJwtTokenAuthenticationFilter

Сообщение было отредактировано: 12 май 20, 22:37
12 май 20, 22:38    [22131633]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2 3 4 5 6 7   вперед  Ctrl      все
Все форумы / Java Ответить