Безопасная работа с данными в многопользовательском WEB-приложении?

Имеется многопользовательское веб-приложение на базе Spring, работающее с базой данных. Аутентификация и авторизация пользователей производится через Spring-Security. С базой работаю через JDBC.


Возьмем простую ситуацию — редактирование некой сущности. Для этого в параметрах запроса передаем контроллеру идентификатор этой сущности, подгружаем ее из БД, заполняем форму, редактируем и обновляем в БД.


Вопрос заключается в том, как правильно обеспечить безопасность этой операции, т.е. проконтролировать принадлежность сущности текущему пользователю? Существует ли на этот счет какой-то стандартный паттерн для Спринга?


Сейчас в каждой реализации DAO при выборке сущности передаю помимо ключа имя пользователя (получаемого через principal.getName()) и в sql-запросе контролирую принадлежность. Типа такого:

public void updateGroup(GroupEntity group, String user) {
		jdbcTemplate.update("UPDATE groups SET password = ?, name = ? WHERE group_id = ? AND user_id = ?", 
				group.getPassword(), group.getName(), group.getId(), user);
}



При отдалении целевой сущности от таблицы, содержащей пользователей, приходится писать все более изощренные запросы. Может быть есть более правильный путь?
  • Вопрос задан
  • 3922 просмотра
Решения вопроса 1
Все можно разрулить через Spring Security. Через Method Security Expressions. В базе у каждой записи должен быть owner_id — внешний ключ на владельца. Код из приведенного вами примера выглядел бы как то так:

@PreAuthorize("#group.owner == authentication.name")
public void updateGroup(GroupEntity group) {
    //
}

Возможны и более сложные варианты.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@sergei-grigorev
Как вариант — использовать отдельные namespaces, тогда сущности не будут доступны посторонним пользователям даже на чтение (используя уязвимости системы, где вы забудете поставить фильтр по пользователю). Тогда будет что-то вроде
public void updateGroup(GroupEntity group, String usernamespace) {
        jdbcTemplate.update("UPDATE " + usernamespace + ".groups SET password = ?, name = ? WHERE group_id = ?", 
                group.getPassword(), group.getName(), group.getId());
}
<source>
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы