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

Spring -Security: вызов метода после аутентификации

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

4b9b3361

Ответ 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 цепочку фильтров безопасности