Как динамически обновлять права пользователя в spring security?
Я написал своий UserDetailsService который через JPA читает из кастомной базы пользователей и их права
При изменении прав пользователя в базе, права в самом приложении не изменяются.
Насколько я понял проблема в том что спринг их закешировал. Есть способ привязать этот кеш к текущему запросу? Или это мой косяк, а спринг и так кеш сбрасывает?
Re: Spring Security обновить права пользователя в рантайме
Здравствуйте, dotidot, Вы писали:
D>Как динамически обновлять права пользователя в spring security? D>Я написал своий UserDetailsService который через JPA читает из кастомной базы пользователей и их права D>При изменении прав пользователя в базе, права в самом приложении не изменяются. D>Насколько я понял проблема в том что спринг их закешировал. Есть способ привязать этот кеш к текущему запросу? Или это мой косяк, а спринг и так кеш сбрасывает?
Правильно ли я понимаю, что пользователи и права кэшируются в приложении? Если да, то при изменении прав можно
или изменять кэш объект, или перечитывать из базы.
На самом деле такая структура хранения более сложна в реализации (на постоянно отслеживать изменения), чем хранения объекта
прав пользователя в сессионной куки. В данном случае права будут обновлены после истечения сессии пользователя.
Re[2]: Spring Security обновить права пользователя в рантайм
Здравствуйте, Denis_Orlov, Вы писали:
D_O>прав пользователя в сессионной куки. В данном случае права будут обновлены после истечения сессии пользователя.
это не приемлемо. если управляющий заблокировал пользователя, то он должен быть заблокирован сразу, а то деньги увести успеет 8)
Re[3]: Spring Security обновить права пользователя в рантайм
Здравствуйте, dotidot, Вы писали:
D>Здравствуйте, Denis_Orlov, Вы писали:
D_O>>прав пользователя в сессионной куки. В данном случае права будут обновлены после истечения сессии пользователя. D>это не приемлемо. если управляющий заблокировал пользователя, то он должен быть заблокирован сразу, а то деньги увести успеет 8)
Ясно, тогда стоит рассказать более подробно, как происходит чтение из базы:
1. Как часто
2. Что делается при обновлении прав
Re[4]: Spring Security обновить права пользователя в рантайм
Здравствуйте, Denis_Orlov, Вы писали:
D_O>1. Как часто
думаю мне будет достаточно если на каждый http запрос будет перечитываться пользователь из базы с помощью моего UserDetailsService
D_O>2. Что делается при обновлении прав
в базе меняются роли назначенные на конкретного пользователя, на основе этих прав происходит проверка доступа через spring security к операциям и данным, в контроллерах, jsp, persistance слое
насколько я понял самый прямой способ это сделать фильтр, который сешнманагеру будет это дело подпихивать
Re[5]: Spring Security обновить права пользователя в рантайм
Здравствуйте, dotidot, Вы писали:
D>думаю мне будет достаточно если на каждый http запрос будет перечитываться пользователь из базы с помощью моего UserDetailsService
Вообще говоря данное решение смотрится очень "тяжёлым". Потенциально обращения к базе за профайлом станет очень тонким местом.
D>в базе меняются роли назначенные на конкретного пользователя, на основе этих прав происходит проверка доступа через spring security к операциям и данным, в контроллерах, jsp, persistance слое
Т.е. роли обновляются не через интерфейс приложения а прямо в базе?
D>насколько я понял самый прямой способ это сделать фильтр, который сешнманагеру будет это дело подпихивать
На самом деле проще сделать SecurityManager, который будет реализовывать метод:
public boolean allowAction(userId, actionType);
При этом у SecurityManager должен быть гарантировано самый последний срез данных.
Re[6]: Spring Security обновить права пользователя в рантайм
Здравствуйте, Denis_Orlov, Вы писали:
D_O>Вообще говоря данное решение смотрится очень "тяжёлым". Потенциально обращения к базе за профайлом станет очень тонким местом.
+1 запрос к базе на один http запрос. это совсем не тяжелое решение.
D_O>Т.е. роли обновляются не через интерфейс приложения а прямо в базе?
по всякому.
D_O>На самом деле проще сделать SecurityManager, который будет реализовывать метод: D_O>
D_O> public boolean allowAction(userId, actionType);
D_O>
D_O>При этом у SecurityManager должен быть гарантировано самый последний срез данных.
а вот это уже ручное управление до которого не хочется сваливаться. иначе зачем тогда вообще spring нужен?
Re: Spring Security обновить права пользователя в рантайме
Здравствуйте, dotidot, Вы писали:
D>Как динамически обновлять права пользователя в spring security?
Права пользователя кэшируются в объекте Authentication. Можно создать обертку над этим объектом, переопределив соответствующим образом метод getAuthorities. Например, установив такой фильтр после всех аутентификационных фильтров:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
SecurityContext context = SecurityContextHolder.getContext();
Authentication auth = context.getAuthentication();
if (auth != null && auth.isAuthenticated() && !(auth instanceof MyAuthenticationWrapper)) {
// Новый пользователь - создать обертку
context.setAuthentication(new MyAuthenticationWrapper(auth));
} else if (auth instanceof MyAuthenticationWrapper) {
// Обновить права
((MyAuthenticationWrapper) auth).updateAuthorities();
}
chain.doFilter(request, response);
}