【问题标题】:How to logout User in Spring Security with external call如何通过外部调用在 Spring Security 中注销用户
【发布时间】:2019-01-30 13:54:02
【问题描述】:

我有一个实现了 spring 安全性的 Spring boot 应用程序。用户登录和注销成功工作,我正在使用 jdbc 进行会话存储。 现在我只想实现一个新的休息端点,它接受特定用户的用户名作为参数并注销该用户。 目前我正在使用以下类作为注销实现。

@Component
public class CustomLogoutHandler extends SecurityContextLogoutHandler {

    @Override
    public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
        super.logout(request, response, authentication);
    }

}

但是我的问题是如何使用这个类或内置的 Spring logout 从外部请求中注销用户? 对于 session_store,我正在使用以下配置,并且用户会话已成功保存在数据库中。

    #Spring Session
spring.session.store-type=jdbc
spring.session.jdbc.table-name= SESSION_TABLE

可以手动从表中删除表条目。它会注销用户。 但我想按照正确的 Spring 安全流程进行注销。

谢谢

【问题讨论】:

  • 会话绑定到用户。所以只有用户可以注销。否则,您将需要劫持会话。所以删除表条目可能是你能做的最好的事情。
  • @SimonMartinelli 我们不能使用 sessionRegistry 来检索用户会话并使会话无效。 ?
  • 你试过了吗?您可以遍历所有主体并在 SessionInformation 上调用 expireNow,然后从注册表中删除 SessionInformation。

标签: spring spring-mvc spring-boot spring-security spring-session


【解决方案1】:

以下是我的处理方法:

  • 为注销创建会话范围控制器
  • 创建一个端点并将HttpSession 注入其中
  • 调用端点后会话无效

类似:

@Scope("session")
@Controller
public class LogoutController {

@PostMapping("/logout")
public ResponseEntity logout(HttpSession session) {
session.invalidate();
return new ResponseEntity().ok();
}

} 

我也不确定你为什么不使用 Spring 已经提供的注销配置:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // config your credentials provider here
    }



    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.
        authorizeRequests()
         // protected endpoints config here
        .and()
        .logout().logoutUrl("/logout")
        .and().csrf().disable();
    }

}

您可以使用 POST 直接调用/logout,这将触发注销。

【讨论】:

  • 感谢您的建议。但是我已经在使用 Spring 为他自己的注销用户提供的注销。在我的情况下,要求是从外部呼叫中注销用户。不是他自己。
【解决方案2】:

我认为您可以使用 spring session 来注销特定用户,只需在控制器中自动装配 session 存储库。 如果我很了解您已经配置了 JdbcOperationsSessionRepository,那么您可以这样做:

@Autowired
private org.springframework.session.jdbc.JdbcOperationsSessionRepository sessionRepository;

然后使用您的存储库查找与特定用户相关的会话

sessionRepository.findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, somePrincipalName);

【讨论】:

  • 这是给 JdbcSession 对象。但是spring logout方法需要HttpSession对象。
  • 也许我不明白你需要什么。你说“或内置 Spring 注销以从外部请求中注销用户”。外部请求是与用户会话无关的请求吗?如果是,您可以使用 findByIndexNameAndIndexValue 方法检索用户会话,然后使用 JdbcOperationsSessionRepository 的 delete 方法将其删除。与从表中删除相同,但由 spring 完成
  • 是的,你是对的。我会这样做,并将其标记为答案:) 谢谢
猜你喜欢
  • 2017-11-05
  • 1970-01-01
  • 1970-01-01
  • 2013-04-29
  • 2014-12-11
  • 2012-07-31
  • 1970-01-01
  • 2017-05-20
  • 1970-01-01
相关资源
最近更新 更多