【问题标题】:How to do something after the login with Spring Security?使用 Spring Security 登录后如何做某事?
【发布时间】:2024-01-01 12:56:01
【问题描述】:

我有一个 Spring Web 应用程序,它使用 Spring SAML 和 Spring Security 来管理登录过程。 现在我需要在正确登录后执行一些任务。特别是我必须在SecurityContext.getContext() 对象中存储一些数据。

我从未使用过 Spring Security/SAML,我不知道它如何管理来自 IdP 的返回。

在登录过程正确结束后,代码中是否有通常可以放置代码的地方?

我的意思是,我知道重定向页面的设置位置,但我无法将自定义代码放入此重定向页面的控制器中,因为该页面被多次访问,并且我只需要在登录时运行我的自定义代码一次时间。

【问题讨论】:

    标签: java spring spring-security spring-saml


    【解决方案1】:

    最好的方法是实现接口SAMLUserDetailsService,它会自动将您从其loadUserBySAML 方法返回的对象存储在Authentication 对象中,您以后可以从SecurityContext.getContext() 查询该对象。每次认证后调用一次接口。有关详细信息和示例,请参阅the manual

    另一种可能性是AuthenticationSuccessHandler。登录过程调用 onAuthenticationSuccess 方法,该方法可以访问 Authentication 对象,该对象将存储在 SecurityContext.getContext() 中。

    只需创建您自己的实现接口AuthenticationSuccessHandler 的类(您还可以扩展一些现有的类,例如SimpleUrlAuthenticationSuccessHandlerAbstractAuthenticationTargetUrlRequestHandler)。然后通过更改现有 successRedirectHandler bean 中的类将您的实现插入到 securityContext.xml

    问题是,Authentication 对象往往是不可变的 - 所以第一种方法可能更好。

    【讨论】:

      【解决方案2】:

      您可以使用 AuthenticationSuccessEvent。只需注册一个实现 ApplicationListener 的 bean。

          @Component
          public class SomeSpringBean implements
                                   ApplicationListener<AuthenticationSuccessEvent> {
      
              public onApplicationEvent(AuthenticationSuccessEvent event) {
                 String userName = ((UserDetails) event.getAuthentication().
                 //do stuff                                       
              }
         }
      

      而且你需要注册AuthenticationEventPublisher。 看这里:https://gist.github.com/msarhan/10834401

      如果您使用自定义身份验证提供程序,您还可以在那里插入任何您想要的东西。

      【讨论】:

      • 感谢 Evgeni 的回复。在我的 WebSecurityConfig 我有这个 bean 定义 pastebin.com/cqBXdu2W 如您所见,它已经定义了一个身份验证成功处理程序方法。问题是,如果我回想successRedirectHandler() 方法中的SecurityContext,它是null
      【解决方案3】:

      你在使用 Spring 的 Java 配置吗?

      如果是这样,那么您的项目中可能有一个覆盖 WebSecurityConfigurerAdapter 的类。扩展此类可以让您访问覆盖方法 configure(HttpSecurity http)。

      您可以使用提供的 HttpSecurity 构建器对象来配置很多东西,其中之一是身份验证成功处理程序。或多或少,您可以创建一个简单的实现 AuthenticationSuccessHandler 的类(Spring 已经为扩展构建了一些类来简化此操作),您可以调用 http.successHandler(yourSuccessHandler) 将其注册到 Spring Security。

      实现该接口为您提供了将自定义代码放入 onAuthenticationSuccess( ... ) 方法的钩子。我认为他们也有一个失败者。

      【讨论】:

      • 谢谢 npm622。调用 AuthenticationSuccessHandler 方法时是否已经设置了 SecurityContext?我的问题是:我需要一个地方来放置我的自定义代码,其中 SecurityContext 已经由 Spring SAML 模块设置
      • 是的......应该是。查看 Spring 的 SecurityContextHolder 类,它有一个静态方法来访问当前的安全上下文。