我試圖找到一種方法來保持數據庫記錄,當用戶通過spring-security進行身份驗證時。同樣,當他們註銷或超時時,我想在那段時間更新該記錄。我一直試圖使用AuthenticationSuccessHandler進行登錄處理,並且LogoutSuccessHandler用於登出。但是,當我使用它時,那麼我的URL在重定向後似乎會中斷。春季安全登錄/註銷登錄
這是我到目前爲止有:
@Component
public class MyLoginSuccessHandler implements AuthenticationSuccessHandler {
public MyLoginSuccessHandler() {
super();
}
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
System.out.println("Logged In User " + (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal());
}
}
和陷阱註銷事件:
@Component
public class MyLogoutSuccessHandler implements LogoutSuccessHandler {
public MyLogoutSuccessHandler() {
super();
}
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException {
System.out.println("Logged OUT User " + (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal());
}
}
而且配置我的安全性,例如:
@Configuration
@EnableWebMvcSecurity
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Autowired
private MyLogoutSuccessHandler myLogoutSuccessHandler;
@Autowired
private MyLoginSuccessHandler myLoginSuccessHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin().failureUrl("/login?error")
.successHandler(myLoginSuccessHandler)
.defaultSuccessUrl("/")
.loginPage("/login")
.permitAll()
.and()
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.permitAll();
http
.sessionManagement()
.maximumSessions(1)
.expiredUrl("/login?expired")
.maxSessionsPreventsLogin(true)
.and()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.invalidSessionUrl("/");
http
.authorizeRequests().anyRequest().authenticated();
http
.logout()
.logoutSuccessHandler(myLogoutSuccessHandler)
.logoutSuccessUrl("/");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
PasswordEncoder encoder = new BCryptPasswordEncoder();
auth.userDetailsService(customUserDetailsService).passwordEncoder(encoder);
}
}
如果我在.successHandler之前放置.defaultSuccessUrl("/")
,然後處理程序被調用,但頁面重定向不會發生,登錄會導致/ login的空白頁面。類似的/註銷。
任何人都可以看到的問題是什麼在這裏
UPDATE: 我增加了執行器和我自己的ApplicationListener:
@Component
public class LoginListener implements ApplicationListener<AuthenticationSuccessEvent> {
private static final Logger LOG = LoggerFactory.getLogger(LoginListener.class);
@Override
public void onApplicationEvent(AuthenticationSuccessEvent event) {
UserDetails ud = (UserDetails) event.getAuthentication().getPrincipal();
LOG.info("User " + ud.getUsername() + " logged in successfully");
}
}
現在,當登錄時,我得到的消息: 2014-11-06 10:10:55.923 INFO 90807 --- [nio-9001-exec-7] osbaaudit.listener.AuditListener:AuditEvent [timestamp = Thu Nov 06 10:10:55 MST 2014,principal = admin, type = AUTHENTICATION_SUCCESS,data = {details = org.springframework.security.web.authentication.WebAuthenticat ionDetails @ 21a2c:RemoteIpAddress:0:0:0:0:0:0:0:1; SessionId:64320375B40CF959936E86F4D1F2973C}]
而且我看到執行的代碼。所以如果我可以到達AuditEvent,我將擁有我的日誌記錄的IP和時間戳。對於註銷,我想盡自己的LogoutHandler:
@Component
public class MyLogoutHandler implements LogoutHandler {
private static final Logger LOG = LoggerFactory.getLogger(MyLogoutHandler.class);
@Override
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
User user = (User) authentication.getPrincipal();
LOG.info("User " + user.getUsername() + " logged OUT successfully");
}
}
我也試圖通過監聽處理:
@Component
public class LogoutListener implements ApplicationListener<SessionDestroyedEvent> {
private static final Logger LOG = LoggerFactory.getLogger(LogoutListener.class);
@Override
public void onApplicationEvent(SessionDestroyedEvent event) {
List<SecurityContext> lstSecurityContext = event.getSecurityContexts();
UserDetails ud;
for (SecurityContext securityContext : lstSecurityContext)
{
ud = (UserDetails) securityContext.getAuthentication().getPrincipal();
LOG.debug("User " + ud.getUsername() + " logged OUT successfully");
}
}
}
沒有這些電話都是以往任何時候都調用。在撥打電話時也不會有任何消息傳送到控制檯。我有一個在
public void sessionDestroyed(HttpSessionEvent arg0) {
totalActiveSessions--;
System.out.println("sessionDestroyed - deduct one session from counter: " + totalActiveSessions);
}
輸出一條消息和一個被稱爲HttpSessionListener類,所以我肯定註銷發生。
見[此](http://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-auditing.html)部的參考指南。添加'spring-boot-starter-actuator'依賴並實現你自己的'AuditEventRepository'。您需要額外的'LogoutHandler'來發布註銷的審計事件(我懷疑),但這是您所需要的。 – 2014-11-06 07:02:49
好主意。或者只是聽'AuthenticationSuccessEvent'。但我不知道是否有註銷事件。 – 2014-11-06 07:08:34
@DaveSyer目前沒有。見[gh-1836](https://github.com/spring-projects/spring-boot/issues/1836)和[SEC-2680](https://jira.spring.io/browse/SEC-2680) 。 – 2014-11-06 11:54:00