Подтвердить что ты не робот

Как немедленно включить полномочия после полномочий пользователя обновлений в spring безопасности?

Я использую spring -security framework. Когда я обновляю разрешения, он не вступает в силу немедленно. Мне нужно выйти из текущего пользователя (означает выход из системы), а затем повторно посетить (означает логин) будет для обновления разрешения пользователя.

Является ли способ, который немедленно разрешает полномочия после полномочий пользователя обновлений в spring безопасности?

4b9b3361

Ответ 1

Вы можете установить alwaysReauthenticate в своем AbstractSecurityInterceptor, как это

<bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
        <property name="alwaysReauthenticate" value="true"/>
 ...
</bean>

Конечно, вы должны обратить внимание, потому что 99,9% вам не нужна повторная аутентификация. Поскольку аутентификация может использовать базу данных или что-то еще, ваша производительность может ухудшиться. Но обычно у вас есть кэш, например, 2-й уровень с спящим режимом, поэтому загрузка userdetails каждый раз должна быть только операцией памяти во всех случаях, когда власти не изменялись.

Ответ 2

Решение Gandalf является действительным, но не полным. Чтобы новые разрешения были рассмотрены с помощью spring безопасности (например, разрешить доступ к ранее недоступным страницам), вам нужно создать новый объект аутентификации (например, новый UsernamePasswordAuthenticationToken), содержащий новый список полномочий.

Ответ 3

Недостаточно для reset локального контекста потока, вам также необходимо обновить сеанс:

UserContext userContext = (UserContext) context.getAuthentication().getPrincipal();
if (userContext != null && userContext.getUsername() != null) {
    //This is my function to refresh the user details
    UserDetailsBean userDetails = getUserDetailsBean(userContext.getUsername());
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    if (authentication instanceof UsernamePasswordAuthenticationToken) {
        UsernamePasswordAuthenticationToken auth = (UsernamePasswordAuthenticationToken) authentication;
        auth.setDetails(userDetails);
    }
    return userDetails;
} else {
    throw new ServiceException("User not authenticated");
}
request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());

По крайней мере, в Google appengine сеанс не является ссылкой и путем изменения локального потока не обновляется автоматически, вам нужно вручную session.set вашего объекта.

Ответ 5

Поскольку вы не совсем точно указали детали в своем вопросе, я предполагаю, что у вас есть ситуация, когда:

  • Вы загружаете UserDetailsService для загрузки UserDetails, когда пользователь пытается войти в систему.
  • В рамках этой службы вы запрашиваете базу данных /DAO для загрузки сведений о разрешениях пользователей и устанавливаете предоставленные полномочия на основе этого
  • Если вы говорите "Когда я обновляю разрешения", вы ссылаетесь на обновление прав пользователя в базе данных (или на то, что вы храните в данных).

Если так, то то, что вы видите, по дизайну - Spring Безопасность загружает UserDetails для пользователя только в первый раз, когда они пытаются войти в систему, а затем сохраняет его в сеансе с этого момента. Как правило, это имеет смысл, поскольку это позволяет избежать того, что приложение может выполнять одни и те же запросы о деталях пользователя для каждого запроса. Кроме того, пользовательские разрешения обычно не меняются в течение 99,9% их посещений.

Чтобы изменить это поведение, вам может понадобиться добавить команду/обновление "Обновить", где будет запускаться некоторый код (который вам придется писать), который будет повторно запрашивать UserDetailsService и заменить UserDetails в SecurityContext. Я не верю, что есть встроенный способ сделать это.

Ответ 6

Вы можете создать собственную реализацию интерфейса UserDetails, который возвращается из механизма аутентификации, который позволяет получить доступ к GrantedAuthorities []. Затем добавьте новые полномочия непосредственно к этому объекту UserDetails. Вы можете столкнуться с проблемами, если пользователь может сразу открыть несколько сеансов (или если у нескольких пользователей есть общий общий логин), что новые разрешения будут видны только в сеансе, который вы изменили.

Ответ 7

Вы можете попробовать это

SecurityContextHolder.getContext().setAuthentication(SecurityContextHolder.getContext().getAuthentication());