Задача:
Получить список залогиненных пользователей (например, чтобы разлогинить некоторых из них).
Решение:
Для решения этой задачи можно воспользоваться реестром пользовательских сессий, который используется Spring Security, в частности, для контроля множественного входа под одним логином. Чтобы реестр заполнялся и к нему можно было получить доступ из собственного кода, нужно (если, конечно, у Вас уже не используется контроль множественного входа):
- В web.xml добавить слушателя:
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener> - В конфигурацию Spring Security добавить:
<!-- Задаем точку входа и страницу запрета доступа, обязательно
-- отключаем auto-config, чтобы определить свой фильтр для входа
-- по логину/паролю
-->
<http auto-config="false" access-denied-page="/login.jsp?accessDeniedError=1"
entry-point-ref="authenticationProcessingFilterEntryPoint">
<custom-filter position="FORM_LOGIN_FILTER" ref="usernamePasswordFilter" />
<!-- Далее идут правила доступа -->
<intercept-url ... />
...
<!-- Указываем ссылку на бин для session-managment`а -->
<session-management session-authentication-strategy-ref="sas"/>
<!-- Конфигурация выхода обыкновенная -->
<logout delete-cookies="JSESSIONID" logout-url="/j_spring_security_logout"/>
</http>
<!-- Конфигурируем точку входа в приложение -->
<beans:bean id="authenticationProcessingFilterEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/login.jsp" />
<beans:property name="forceHttps" value="false" />
</beans:bean>
<!-- Конфигурируем реестр сессий -->
<beans:bean id="sessionRegistry"
class="org.springframework.security.core.session.SessionRegistryImpl" />
<!-- Конфигурируем бин стратегии контроля сессий. Не ограничиваем
-- множественность входа (нам это сейчас не нужно, по этой же причине
-- мы не использовали фильтр ConcurrentSessionFilter)
-->
<beans:bean id="sas" class=
"org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
<beans:constructor-arg ref="sessionRegistry" />
<beans:property name="maximumSessions" value="-1" />
</beans:bean>
<!-- Конфигурируем фильтр входа по логину / паролю, задавая ссылку на стратегию,
-- а также ссылки на бины обработчиков успешного / неуспешного входа
-->
<beans:bean id="usernamePasswordFilter" class=
"org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<beans:property name="sessionAuthenticationStrategy" ref="sas" />
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="authenticationFailureHandler" ref="loginFailureHandler"/>
<beans:property name="authenticationSuccessHandler" ref="loginSuccessHandler"/>
</beans:bean>
<!-- Менеджер аутентификации. Тут все стандартно, задается один какой-то провайдер
-- и для стандартного провайдера задается какой-то UserService
-->
<authentication-manager alias="authenticationManager">
<authentication-provider ref="..."/>
<authentication-provider user-service-ref='...'>
<password-encoder hash="md5" />
</authentication-provider>
</authentication-manager>
<!-- Обработчики успешного / неуспешного логина. Стандартные -->
<beans:bean id="loginSuccessHandler" class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler" >
<beans:property name="defaultTargetUrl" value="/index.jsp"/>
</beans:bean>
<beans:bean id="loginFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler" >
<beans:property name="defaultFailureUrl" value="/login.jsp?loginError=1" />
</beans:bean>
-
Теперь получить реестр и список активных принципалов в коде можно так:
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.web.context.support.WebApplicationContextUtils;
...
ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
SessionRegistry sReg = (SessionRegistry) ac.getBean("sessionRegistry");
for(Object principal: sReg.getAllPrincipals())
System.out.println("Principal: "+principal.toString());
PS Надо, пожалуй, озаботиться подсветкой синтаксиса в блоге =)
Комментариев нет:
Отправить комментарий