Spring-Security: вызов метода после аутентификации - PullRequest
21 голосов
/ 05 апреля 2010

Я хотел бы отслеживать, когда пользователи входят в мое приложение. У меня есть код, который я хотел бы выполнить сразу после аутентификации пользователя. Проблема в том, что я не могу понять, где это должно быть вызвано. Есть ли у Spring-Security способ вызвать метод после аутентификации?

Ответы [ 7 ]

31 голосов
/ 31 августа 2012

, вероятно, будет полезно для кого-то ... В случае 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.

11 голосов
/ 25 мая 2012

Лучший способ - создать прослушиватель приложения и зарегистрировать его в контексте безопасности 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-компонента. Есть много других типов прослушивателей событий безопасности, которые вы можете слушать, проверьте иерархию типов для списка всех типов событий безопасности, которые вы можете прослушать.

6 голосов
/ 01 августа 2013

Если вы хотите продолжить с поведением по умолчанию, но в промежутке между выполнением своей собственной бизнес-логики, вы можете extend SimpleUrlAuthenticationSuccessHandler и вызвать super.onAuthenticationSuccess(request, response, authentication);, прежде чем вернуться. Подробнее см. https://stackoverflow.com/a/6770785/418439

4 голосов
/ 05 апреля 2010

Просто напишите свой собственный 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>
2 голосов
/ 30 декабря 2016

Если вы хотите не читать всю ветку: кураторская версия с аннотациями и чуть более пояснительными:

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");

    } 
}
1 голос
/ 15 декабря 2015

Аутентификация не обязательно означает успешный вход в систему. Пользователь может быть успешно аутентифицирован с помощью, например, двухстороннего SSL (сертификаты X.509), и, тем не менее, Spring Security перенаправит вас на страницу с ошибкой, если управление параллельным сеансом настроено с max-sessions="1", и это второй одновременный вход в систему попытка. Если ваша настройка проста, без контроля параллелизма сеанса, вы можете принять логин = аутентификацию для всех практических целей. В противном случае, если у вас есть, например, логика, которая записывает каждый успешный вход в базу данных, вам придется вызывать эту логику в момент фактического входа, а не в момент аутентификации. , Один из способов (ни в коем случае не оптимальный, при условии моего ограниченного понимания инфраструктуры Spring Security) сделать это - реализовать свой собственный ConcurrentSessionControlAuthenticationStrategy (нажмите здесь для исходного кода) и вставить его в CompositeSessionAuthenticationStrategy в XML-конфигурации конфигурации Spring Security (3.2 и выше):

<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 и вносить в него изменения, но я не знаю, как это сделать. сделай это в данный момент.

Более полный пример конфигурации можно найти здесь .

0 голосов
/ 05 июня 2011

Эта ссылка Логика пост-аутентификации в ByteClip объясняет, как выполнить некоторую логику после успешной аутентификации, не нарушая цепочку фильтров безопасности пружины

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...