簡體   English   中英

如何在 Spring Boot 應用程序中使用 Spring Security 監聽登錄/注銷事件?

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

我試圖在 Spring Security 中成功/失敗登錄/注銷后記錄消息。

另外,我使用的是 Spring Boot,所以配置代碼很少。

我使用的表格是自動生成的。

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>

我的登錄成功代碼如下:

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

它不會工作。 我在日志中什么也沒有。

如果有的話,我需要編寫哪些額外的代碼? 我需要在任何地方初始化這個監聽器嗎?

我也使用此鏈接作為參考,但我認為我不需要編寫出版商,因為我沒有為該活動編寫自己的課程。

我也嘗試過AuthenticationSuccessEvent而不是InteractiveAuthenticationSuccessEvent ,但同樣的事情。

如果有幫助,登錄失敗會產生以下輸出(預期輸出應包括“登錄失敗”和當前日期,這是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

結果證明該錯誤與配置有關。

為了捕獲登錄事件,我使用了對象

InteractiveAuthenticationSuccessEventAuthenticationSuccessEvent (注銷還沒有實現的偵聽器,您可能會使用HttpSessionEvent )。

此外,查看記錄器是否配置為記錄您的包也很重要; 默認情況下,應用程序未配置為記錄應用程序消息。 這就是為什么我沒有得到任何輸出。

所以,兩件事:

  • 如果您的包名稱是com.mycompany ,您應該在application.propertiesapplication.yml文件(通常在<PROJ_DIR>/src/main/resources/ ;如果沒有,請創建自己的)中添加一行用於記錄:

application.properties

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

或者:

application.yml :

logging:
    level:
        com:
            mycompany: DEBUG/INFO/WARN/ERROR
  • 如果您嘗試記錄外部包,請使用debug()方法記錄它,否則它可能不會顯示(我使用了info()我什么也沒得到)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM