Я хочу отслеживать, когда пользователи регистрируются в моем приложении. У меня есть код, который я хотел бы выполнить сразу после аутентификации пользователя. Проблема в том, что я не могу понять, где это следует назвать. Имеет ли spring -security способ вызова метода после аутентификации?
Spring -Security: вызов метода после аутентификации
Ответ 1
вероятно, будет полезно для кого-то... В случае Spring 3 настройте безопасность:
<security:http use-expressions="true" auto-config="true">
<security:intercept-url pattern="..."/>
<security:form-login
authentication-failure-handler-ref="authFailureHandler"
authentication-success-handler-ref="authSuccessHandler"/>
<security:logout success-handler-ref="logoutSuccessHandler"
invalidate-session="true"/>
<security:session-management session-fixation-protection="newSession"/>
</security:http>
<bean id="authFailureHandler" class="mine.AuthenticationFailureHandlerImpl"/>
<bean id="authSuccessHandler" class="mine.AuthenticationSuccessHandlerImpl"/>
<bean id="logoutSuccessHandler" class="mine.LogoutSuccessHandlerImpl"/>
и реализовать соответствующий класс:
public class AuthenticationSuccessHandlerImpl implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
//do what you want with
response.getOutputStream().write("success".getBytes());
}
}
Вы можете связать ресурсы через эту конфигурацию xml.
Ответ 2
Лучший способ - создать прослушиватель приложений и зарегистрировать его с помощью контекста безопасности spring.
import org.springframework.context.ApplicationListener;
import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent;
public class AuthenticationSuccessListener implements ApplicationListener<InteractiveAuthenticationSuccessEvent> {
@Override
public void onApplicationEvent(InteractiveAuthenticationSuccessEvent event) {
System.out.println("User Logged In");
}
}
Обязательно добавьте вышеприведенный класс spring -security.xml как bean. Есть много других типов прослушивателей событий безопасности, которые вы можете прослушать, проверьте иерархию типов для списка всех типов событий безопасности, которые вы можете прослушать.
Ответ 3
Если вы хотите продолжить поведение по умолчанию, но только между вашей собственной бизнес-логикой, вы можете extend SimpleUrlAuthenticationSuccessHandler
и вызвать super.onAuthenticationSuccess(request, response, authentication);
перед возвратом. Подробнее см. fooobar.com/questions/267915/...
Ответ 4
Просто напишите свой собственный SpringSecurityFilter и добавьте его в цепочку фильтров сразу после вызова поставщика проверки подлинности.
package my.code;
public class AuditFilter extends SpringSecurityFilter {
public void doFilterHttp(...) throws ... {
{application code to run before request is processed}
chain.doFilter(...);
{application code to run after request has fully processed}
}
}
Затем в вашей конфигурации XML (везде, где вы настраиваете цепочку фильтра безопасности) добавьте следующую строку:
<bean id="auditFilter" class="my.code.AuditFilter>
<security:custom-filter position="LAST"/> <-- you can change the position
</bean>
Ответ 5
Если вы хотите избежать чтения всего потока: кураторская версия с аннотациями и немного более пояснительная:
import org.springframework.context.ApplicationListener;
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
@Component
public class LoginSuccessListener implements ApplicationListener<AuthenticationSuccessEvent{
@Override
public void onApplicationEvent(AuthenticationSuccessEvent evt) {
// if you just need the login
String login = evt.getAuthentication().getName();
System.out.println(login + " has just logged in");
// if you need to access full user (ie only roles are interesting -- the rest is already verified as login is successful)
User user = (User) evt.getAuthentication().getPrincipal();
System.out.println(user.getUsername() + " has just logged in");
}
}
Ответ 6
Аутентификация не обязательно означает успешный вход в систему. Пользователь может быть успешно аутентифицирован посредством, например, двухстороннего SSL (сертификаты X.509) и Spring. Безопасность перенаправит вас на страницу с ошибкой, если управление сеансом concurrency настроено с помощью max-sessions="1"
, и это вторая попытка одновременного входа в систему. Если ваша настройка проста, без управления сеансом concurrency, вы можете использовать login = authentication для всех практических целей. В противном случае, если у вас есть, например, логика, которая записывает каждый успешный логин в базе данных, вам придется вызывать эту логику в точке фактического входа, а не в момент аутентификации. Один из способов (отнюдь не оптимальный, с учетом моего ограниченного понимания структуры безопасности Spring) - это реализовать свой собственный ConcurrentSessionControlAuthenticationStrategy
(нажмите здесь для исходного кода) и введите его в CompositeSessionAuthenticationStrategy
в конфигурацию Spring Security (3,2 и выше) XML:
<http>
.
.
<session-management session-authentication-strategy-ref="sas" />
.
.
</http>
.
.
<beans:bean id="sas" class="org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy">
<beans:constructor-arg>
<beans:list>
<beans:bean class="path.to.my.implementation.of.ConcurrentSessionControlAuthenticationStrategy">
<beans:constructor-arg ref="sessionRegistry"/>
<beans:property name="maximumSessions" value="1"/>
<beans:property name="exceptionIfMaximumExceeded" value="true"/>
<beans:bean>
<beans:bean class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy"/>
<beans:bean class="org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy"/>
<beans:constructor-arg ref="sessionRegistry"/>
</beans:bean>
</beans:list>
</beans:constructor-arg>
</beans:bean>
<beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl"/>
Я предпочел бы добавить пользовательский обработчик PostLogin
в фреймворк ConcurrentSessionControlAuthenticationStrategy
вместо того, чтобы копировать его в свой пользовательский ConcurrentSessionControlAuthenticationStrategy
и вносить в него изменения, но я не знаю, как сделайте это в данный момент.
Более полный пример конфигурации можно найти здесь.
Ответ 7
Эта ссылка Post Authentication Logic в ByteClip объясняет, как выполнить некоторую логику после успешной аутентификации, не нарушая spring цепочку фильтров безопасности