Spring-Security: Call method after authentication

后端 未结 7 1328
一整个雨季
一整个雨季 2021-02-01 04:52

I\'d like to track when users are logging in to my application. I have some code that I would like to execute right after the user is authenticated. The problem is, I can\'t fig

相关标签:
7条回答
  • 2021-02-01 05:19

    If you want to avoid reading all the thread : curated version with annotations & a bit more explanatory :

    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");
    
        } 
    }
    
    0 讨论(0)
  • 2021-02-01 05:20

    Just write your own SpringSecurityFilter and add it to the filter chain right after your authentication provider is called.

    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} 
       }
    }
    

    Then in your configuration XML (wherever you setup the Security Filter chain) add a line like this:

    <bean id="auditFilter" class="my.code.AuditFilter>
       <security:custom-filter position="LAST"/>  <-- you can change the position
    </bean>
    
    0 讨论(0)
  • 2021-02-01 05:22

    probably will be usefull for someone... In case of Spring 3, configure security:

    <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"/>
    

    and implement an appropriate class:

    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());
        }
    }
    

    You can link resources via that xml config.

    0 讨论(0)
  • 2021-02-01 05:22

    In case you want to continue with default behavior but just in between perform your own business logic, you may extend SimpleUrlAuthenticationSuccessHandler and invoke super.onAuthenticationSuccess(request, response, authentication); before you return. More details refer to https://stackoverflow.com/a/6770785/418439

    0 讨论(0)
  • 2021-02-01 05:25

    Authentication does not necessarily imply successful login. A user can be successfully authenticated via, e.g., two-way SSL (X.509 certs), and still Spring Security will redirect you to an error page if session concurrency management is set up with max-sessions="1" and this is a second concurrent login attempt. If your setup is simple, without session concurrency control, you can assume login = authentication for all practical purposes. Otherwise, if you have, e.g., logic that records every successful login in a database, you will have to invoke this logic at the point of actual login, not at the point of authentication. One way (by no means optimal, subject to my limited understanding of the Spring Security framework) to do this is to implement your own ConcurrentSessionControlAuthenticationStrategy (click here for the source code) and inject it into CompositeSessionAuthenticationStrategy in your Spring Security (3.2 and above) configuration 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"/>
    

    I would have preferred to inject a custom PostLogin handler into the framework's ConcurrentSessionControlAuthenticationStrategy, instead of copy-pasting from it into my custom ConcurrentSessionControlAuthenticationStrategy and making modifications to it, but I do not know of a way to do this at the moment.

    A more complete configuration example can be found here.

    0 讨论(0)
  • 2021-02-01 05:34

    This link Post Authentication Logic on ByteClip explains how to execute some logic after successful authentication without disturbing spring security filter chain

    0 讨论(0)
提交回复
热议问题