2012-03-28 2 views
22

Я делаю приложение с аутентификацией по OpenID с использованием Spring Security. Когда пользователь вошел в систему, некоторые полномочия загружаются в его сеанс.Как перезагрузить полномочия при обновлении пользователя с помощью Spring Security

У меня есть Пользователь с полным правом, который может изменять полномочия (отменять, добавлять роли) других пользователей. Мой вопрос заключается в том, как динамически менять полномочия пользовательской сессии? (не может использовать SecurityContextHolder, потому что я хочу изменить другую сессию пользователя).

Простой способ: аннулировать сеанс пользователя, но как это сделать? Лучший способ: обновить сеанс пользователя новыми полномочиями, но как?

ответ

6

Ключевой момент - вы должны иметь доступ к пользователям SecurityContext s.

Если вы находитесь в сервлет среде и используют HttpSession как securityContextRepository в вашем securityContextPersistenceFilter, то это может быть сделано с весны SessionRegistry. Чтобы заставить пользователя повторно авторизироваться (он должен быть лучше, чем молчание разрешения), аннулирует его HttpSession. Не забудьте добавить HttpSessionEventPublisher в web.xml

<listener> 
    <listener-class> 
     org.springframework.security.web.session.HttpSessionEventPublisher 
    </listener-class> 
</listener> 

Если вы используете нить локального securityContextRepository, то вы должны добавить пользовательский фильтр springSecurityFilterChain управлять SecurityContext сек реестра. Для этого вы должны использовать конфигурацию plain-bean springSecurityFilterChain (без ярлыков имен security). С простой конфигурацией с настраиваемыми фильтрами вы будете иметь полный контроль над аутентификацией и авторизацией.

Некоторые ссылки, они не решают именно вашу проблему (не OpenID), но может быть полезно:

7

Спасибо, помогите мне много! С помощью SessionRegistry я могу использовать getAllPrincipals(), чтобы сравнить пользователя с текущими активными пользователями в сеансах. Если сеанс существует, я могу аннулировать его сеанс, используя: expireNow() (от SessionInformation) для принудительной повторной аутентификации.

Но я не понимаю полезности securityContextPersistenceFilter?

EDIT:

// user object = User currently updated 
// invalidate user session 
List<Object> loggedUsers = sessionRegistry.getAllPrincipals(); 
for (Object principal : loggedUsers) { 
    if(principal instanceof User) { 
     final User loggedUser = (User) principal; 
     if(user.getUsername().equals(loggedUser.getUsername())) { 
      List<SessionInformation> sessionsInfo = sessionRegistry.getAllSessions(principal, false); 
      if(null != sessionsInfo && sessionsInfo.size() > 0) { 
       for (SessionInformation sessionInformation : sessionsInfo) { 
        LOGGER.info("Exprire now :" + sessionInformation.getSessionId()); 
        sessionInformation.expireNow(); 
        sessionRegistry.removeSessionInformation(sessionInformation.getSessionId()); 
        // User is not forced to re-logging 
       } 
      } 
     } 
    } 
} 
+0

'securityContextPersistenceFilter' по умолчанию поместит' 'SecurityContext' в HttpSession' в сервлет среде. Поскольку у вас уже есть готовая пружина 'SessionRegistry', вам не нужно настраивать этот фильтр. – alexkasko

+0

Я в среде сервлета, в чем польза настройки securityContextPersistenceFilter? – Aure77

+0

возможны различные случаи, например. 'HttpSession' отключены, и вы не хотите локального хранилища потоков. Таким образом, вы можете использовать собственную реализацию 'securityContextRepository'. Если хранилище «HttpSession» соответствует вашим потребностям, тогда нет никакой пользы. – alexkasko

22

Если вам нужно динамически обновлять вошедшие полномочия пользователя (если они изменились, по какой-либо причине), без того, чтобы выйти и войти конечно, вам просто нужно сбросьте объект Authentication (токен безопасности) весной SecurityContextHolder.

Пример:

Authentication auth = SecurityContextHolder.getContext().getAuthentication(); 

List<GrantedAuthority> updatedAuthorities = new ArrayList<>(auth.getAuthorities()); 
updatedAuthorities.add(...); //add your role here [e.g., new SimpleGrantedAuthority("ROLE_NEW_ROLE")] 

Authentication newAuth = new UsernamePasswordAuthenticationToken(auth.getPrincipal(), auth.getCredentials(), updatedAuthorities); 

SecurityContextHolder.getContext().setAuthentication(newAuth); 
+5

Ну, это почти сработало для меня. Эта переменная «auth» относится к зарегистрированному пользователю (то есть мне). Если я зарегистрирован как «x», и я хотел бы отменить полномочия «y», как мне получить объект аутентификации от этого конкретного пользователя? – Paulo

Смежные вопросы