gpt4 book ai didi

spring-security - Spring Security 登录/注销的日志记录

转载 作者:行者123 更新时间:2023-12-05 07:57:33 28 4
gpt4 key购买 nike

我正在尝试找到一种方法来在用户通过 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 );
}
}

如果我将 .defaultSuccessUrl( "/") 放在 .successHandler 之前,则会调用处理程序,但页面重定向不会发生并且登录会导致空白页面/login ./logout 也是如此。

谁能看出这是什么问题

更新:我添加了 Actuator 和我自己的 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] o.s.b.a.audit.listener.AuditListener:AuditEvent [timestamp=Thu Nov 06 10:10:55 MST 2014,principal=admin,类型=AUTHENTICATION_SUCCESS,数据={details=org.springframework.security.web.authentication.WebAuthenticationDetails@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");
}
}
}

这些调用都没有被调用。 /logout 调用时,也不会向控制台发送任何消息。我有一个在

上输出消息的 HttpSessionListener 类
 public void sessionDestroyed(HttpSessionEvent arg0) {
totalActiveSessions--;
System.out.println("sessionDestroyed - deduct one session from counter: " + totalActiveSessions);
}

那个被调用了,所以我确定注销发生了。

最佳答案

我在注销后做其他事情时遇到了同样的问题,并通过以下方式解决了它:

  • 我使用,就像您在更新方法中一样,ApplicationListener<SessionDestroyedEvent> .
  • 但是你还必须添加一个 HttpSessionEventPublisher到您的部署描述符。 this 中描述了原因页。简而言之:
    Session-Destroyed 事件是 Java EE HttpSessionEvent s,发生在 Spring 环境之外。您可以使用 Java EE 捕获它们 HttpSessionListener .但是如果你想访问 Spring 相关的 beans - f.e. Spring-Authentication - 然后你必须添加 HttpSessionEventPublisher - 它将 Java-EE-Events 转换为 Spring-Events:

    <listener>
    <listener-class>
    org.springframework.security.web.session.HttpSessionEventPublisher
    </listener-class>
    </listener>

在此之后你可以 catch SessionDestroyedEvent像这样:

@Component
public class AuthenticationApplicationListener {

@EventListener
public void handleSessionDestroyedEvent(SessionDestroyedEvent event) {
List<SecurityContext> lstSecurityContext = event.getSecurityContexts();
for (SecurityContext securityContext : lstSecurityContext) {

//Try to find out, if this event is caused by a logout,
//This is true, when the old session has been an authenticated one.
Authentication auth = securityContext.getAuthentication();
if (auth == null ||
!auth.isAuthenticated() ||
auth instanceof AnonymousAuthenticationToken) {
return;
}

//do something
}
}


与 Success-Handler 相比,这种方法有一些优势:

  • 当您使用编程注销时(例如通过 HttpServletRequest.logout() ),它也能正常工作
  • 当您通过 url 注销时,它不会中断过滤器链。


另见 this answer

关于spring-security - Spring Security 登录/注销的日志记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26771270/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com