简体   繁体   English

如何在 Spring Boot 应用程序中使用 Spring Security 监听登录/注销事件?

[英]How to listen for login/logout events using Spring Security in a Spring Boot application?

I am trying to log messages after a successful/failed login/logout in Spring Security.我试图在 Spring Security 中成功/失败登录/注销后记录消息。

Also, I'm using Spring Boot, so there is little configuration code.另外,我使用的是 Spring Boot,所以配置代码很少。

The form that I am using is auto-generated.我使用的表格是自动生成的。

WebSecurityConfig.java

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
            .authorizeRequests()
                .antMatchers("/resources/**").permitAll()
                .anyRequest().fullyAuthenticated()
                .and()
            .formLogin();

    }

    @Configuration
    protected static class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter {

        @Override
        public void init(AuthenticationManagerBuilder auth) throws Exception {
            auth
                .ldapAuthentication()
                .userSearchFilter("(uid={0})")
                .contextSource()
                .url("ldap://...:389/ou=...,dc=...,dc=...")
                .managerDn("cn=...,dc=...,dc=...")
                .managerPassword("...");
        }
    }
}

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml"/>
</configuration>

My code for login success is as follows:我的登录成功代码如下:

LoginSuccessService.java

import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.security.authentication.event.*;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

@Component
public class LoginSuccessService implements ApplicationListener<InteractiveAuthenticationSuccessEvent>{

    private static final Logger logger = LoggerFactory.getLogger(LoginSuccessService.class);

    @Override
    public void onApplicationEvent(InteractiveAuthenticationSuccessEvent event) {
        logger.debug("You have been logged in successfully.");
        Date loginDate = new Date();
        logger.debug("Login Time: " + loginDate.toString());
    }
}

It won't work.它不会工作。 I get nothing in the log.我在日志中什么也没有。

What additional code do I need to write, if any?如果有的话,我需要编写哪些额外的代码? Do I need to initialize this listener anywhere?我需要在任何地方初始化这个监听器吗?

I also used this link as reference, but I figured I didn't need to write a publisher, as I am not writing my own class for the event.我也使用此链接作为参考,但我认为我不需要编写出版商,因为我没有为该活动编写自己的课程。

I have also tried with AuthenticationSuccessEvent instead of InteractiveAuthenticationSuccessEvent , but same thing.我也尝试过AuthenticationSuccessEvent而不是InteractiveAuthenticationSuccessEvent ,但同样的事情。

If it helps, a failed login produces the following output(expected output should include "Failed to log in" and the current date, this is a log with debug=TRUE in application.properties ):如果有帮助,登录失败会产生以下输出(预期输出应包括“登录失败”和当前日期,这是application.properties debug=TRUE 的日志):

2016-03-16 18:50:12.779 DEBUG 8895 --- [nio-8080-exec-7] o.s.b.c.web.OrderedRequestContextFilter  : Bound request context to thread: org.apache.catalina.connector.RequestFacade@67a404ea
2016-03-16 18:50:12.779 DEBUG 8895 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /login at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-03-16 18:50:12.779 DEBUG 8895 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /login at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2016-03-16 18:50:12.779 DEBUG 8895 --- [nio-8080-exec-7] w.c.HttpSessionSecurityContextRepository : Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@56979972: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@56979972: Principal: org.springframework.security.ldap.userdetails.LdapUserDetailsImpl@a96aab26: Dn: cn=User,ou=users,dc=vs,dc=local; Username: user; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; CredentialsNonExpired: true; AccountNonLocked: true; Not granted any authorities; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@2cd90: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 524F4F9744824535095B43C18FBA71F4; Not granted any authorities'
2016-03-16 18:50:12.780 DEBUG 8895 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /login at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2016-03-16 18:50:12.780 DEBUG 8895 --- [nio-8080-exec-7] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@3a3c5471
2016-03-16 18:50:12.780 DEBUG 8895 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /login at position 4 of 13 in additional filter chain; firing Filter: 'CsrfFilter'
2016-03-16 18:50:12.780 DEBUG 8895 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /login at position 5 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
2016-03-16 18:50:12.780 DEBUG 8895 --- [nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/logout'
2016-03-16 18:50:12.780 DEBUG 8895 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /login at position 6 of 13 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2016-03-16 18:50:12.780 DEBUG 8895 --- [nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/login'
2016-03-16 18:50:12.780 DEBUG 8895 --- [nio-8080-exec-7] w.a.UsernamePasswordAuthenticationFilter : Request is to process authentication
2016-03-16 18:50:12.780 DEBUG 8895 --- [nio-8080-exec-7] o.s.s.authentication.ProviderManager     : Authentication attempt using org.springframework.security.ldap.authentication.LdapAuthenticationProvider
2016-03-16 18:50:12.780 DEBUG 8895 --- [nio-8080-exec-7] o.s.s.l.a.LdapAuthenticationProvider     : Processing authentication request for user: iprnein
2016-03-16 18:50:12.780 DEBUG 8895 --- [nio-8080-exec-7] o.s.s.l.s.FilterBasedLdapUserSearch      : Searching for user 'iprnein', with user search [ searchFilter: '(uid={0})', searchBase: '', scope: subtree, searchTimeLimit: 0, derefLinkFlag: false ]
2016-03-16 18:50:12.781 DEBUG 8895 --- [nio-8080-exec-7] o.s.l.c.support.AbstractContextSource    : Got Ldap context on server 'ldap://192.168.10.41:389/ou=users,dc=vs,dc=local'
2016-03-16 18:50:12.788 DEBUG 8895 --- [nio-8080-exec-7] o.s.s.ldap.SpringSecurityLdapTemplate    : Searching for entry under DN 'ou=users,dc=vs,dc=local', base = '', filter = '(uid={0})'
2016-03-16 18:50:12.789 DEBUG 8895 --- [nio-8080-exec-7] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'loginFailureService'
2016-03-16 18:50:12.790 DEBUG 8895 --- [nio-8080-exec-7] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'delegatingApplicationListener'
2016-03-16 18:50:12.790 DEBUG 8895 --- [nio-8080-exec-7] w.a.UsernamePasswordAuthenticationFilter : Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
2016-03-16 18:50:12.790 DEBUG 8895 --- [nio-8080-exec-7] w.a.UsernamePasswordAuthenticationFilter : Updated SecurityContextHolder to contain null Authentication
2016-03-16 18:50:12.790 DEBUG 8895 --- [nio-8080-exec-7] w.a.UsernamePasswordAuthenticationFilter : Delegating to authentication failure handler org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler@19d8353
2016-03-16 18:50:12.790 DEBUG 8895 --- [nio-8080-exec-7] .a.SimpleUrlAuthenticationFailureHandler : Redirecting to /login?error
2016-03-16 18:50:12.790 DEBUG 8895 --- [nio-8080-exec-7] o.s.s.web.DefaultRedirectStrategy        : Redirecting to '/login?error'
2016-03-16 18:50:12.790 DEBUG 8895 --- [nio-8080-exec-7] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2016-03-16 18:50:12.790 DEBUG 8895 --- [nio-8080-exec-7] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2016-03-16 18:50:12.790 DEBUG 8895 --- [nio-8080-exec-7] o.s.b.c.web.OrderedRequestContextFilter  : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@67a404ea
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] o.s.b.c.web.OrderedRequestContextFilter  : Bound request context to thread: org.apache.catalina.connector.RequestFacade@67a404ea
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy        : /login?error at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy        : /login?error at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@68e82290. A new one will be created.
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy        : /login?error at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@3a3c5471
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy        : /login?error at position 4 of 13 in additional filter chain; firing Filter: 'CsrfFilter'
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy        : /login?error at position 5 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /login' doesn't match 'POST /logout
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy        : /login?error at position 6 of 13 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /login' doesn't match 'POST /login
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy        : /login?error at position 7 of 13 in additional filter chain; firing Filter: 'DefaultLoginPageGeneratingFilter'
2016-03-16 18:50:12.801 DEBUG 8895 --- [nio-8080-exec-9] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2016-03-16 18:50:12.801 DEBUG 8895 --- [nio-8080-exec-9] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2016-03-16 18:50:12.801 DEBUG 8895 --- [nio-8080-exec-9] o.s.b.c.web.OrderedRequestContextFilter  : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@67a404ea

The error turned out to be configuration-related.结果证明该错误与配置有关。

For capturing login events, I used the objects为了捕获登录事件,我使用了对象

InteractiveAuthenticationSuccessEvent or AuthenticationSuccessEvent (logout doesn't have an implemented listener yet, you might have luck with HttpSessionEvent ). InteractiveAuthenticationSuccessEventAuthenticationSuccessEvent (注销还没有实现的侦听器,您可能会使用HttpSessionEvent )。

Also, it's important to see whether or not the logger is configured to log your package;此外,查看记录器是否配置为记录您的包也很重要; the application is not configured by default to log application messages.默认情况下,应用程序未配置为记录应用程序消息。 That is why I was not getting any output.这就是为什么我没有得到任何输出。

So, two things:所以,两件事:

  • If your package name is com.mycompany , you should add a line in your application.properties or application.yml file(usually found in <PROJ_DIR>/src/main/resources/ ; if not, create your own) for logging:如果您的包名称是com.mycompany ,您应该在application.propertiesapplication.yml文件(通常在<PROJ_DIR>/src/main/resources/ ;如果没有,请创建自己的)中添加一行用于记录:

application.properties : application.properties

logging.level.com.mycompany=DEBUG/INFO/WARN/ERROR 
    #debug is lowest, error is highest

or:或者:

application.yml : application.yml :

logging:
    level:
        com:
            mycompany: DEBUG/INFO/WARN/ERROR
  • If you are trying to log an outside package, log it with the debug() method or it might not show up(I used info() and I got nothing).如果您尝试记录外部包,请使用debug()方法记录它,否则它可能不会显示(我使用了info()我什么也没得到)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM