[英]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
). InteractiveAuthenticationSuccessEvent
或AuthenticationSuccessEvent
(注销还没有实现的侦听器,您可能会使用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:所以,两件事:
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.properties
或application.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
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.