【问题标题】:Logout logic is not working with basic authentication注销逻辑不适用于基本身份验证
【发布时间】:2019-10-14 20:50:15
【问题描述】:

这是我的注销代码。它被重定向到logout.done,但是,如果我再次转到hello,我仍然可以访问它。

public void configure(HttpSecurity http) throws Exception {
    http.httpBasic().and().authorizeRequests().anyRequest().authenticated().antMatchers(HttpMethod.GET, "/hello/**").hasRole("user")
    .and()
    .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
    .logoutSuccessUrl("/logout.done").deleteCookies("JSESSIONID")
    .invalidateHttpSession(true);
}

这里有什么问题?

【问题讨论】:

  • 您是否尝试添加clearAuthentication(true)?在.logout() 之后可以像..logout().clearAuthentication(true).. 一样添加它
  • 基本身份验证和注销不起作用。一旦您注销,您将再次登录,因为客户端可能会再次发送基本标头。如果您使用的是 js 客户端,请确保在客户端上也保留基本身份验证标头。

标签: spring spring-security


【解决方案1】:

这段代码对我有用:

public void configure(HttpSecurity http) throws Exception {
    http.httpBasic().and().authorizeRequests().anyRequest().authenticated().antMatchers(HttpMethod.GET, "/hello/**").hasRole("user").and().formLogin().and()
    .httpBasic()
    .and()
    .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
    .logoutSuccessUrl("/logout.done").deleteCookies("JSESSIONID")
    .invalidateHttpSession(true).clearAuthentication(true);
}

【讨论】:

    【解决方案2】:

    添加 Spring 安全性和特定控制器

    public void configure(HttpSecurity http) throws Exception {
        http.httpBasic().and().authorizeRequests().anyRequest().authenticated().antMatchers(HttpMethod.GET, "/hello/**").hasRole("user")
        .and()
        .logout()
        .logoutSuccessUrl("/login?logout").invalidateHttpSession(true).deleteCookies("JSESSIONID");
    }
    
        @RequestMapping(value = { "/", "/login" }, method = RequestMethod.GET)
    public ModelAndView adminLogin(Model model,@RequestParam(value = "error", required = false) String error,
            @RequestParam(value = "logout", required = false) String logout, 
            @RequestParam(value = "expired", required = false) String expired,
            @RequestParam(value = "accessdenied", required = false) String accessdenied,
            HttpServletRequest request, HttpServletResponse response) {
        if (logout != null) {
            logger.info("logout application");
            SecurityContextHolder.getContext().setAuthentication(null);
            SecurityContextHolder.clearContext();
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
            if (auth != null){   
                new SecurityContextLogoutHandler().logout(request, response, auth);
            }
            HttpSession session = request.getSession(false);
            Enumeration<?> e = session.getAttributeNames();
            while (e.hasMoreElements()) {
                String attr = (String) e.nextElement();
                session.setAttribute(attr, null);
            }
            if (session != null) {
                session.removeAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
                session.invalidate();
            }
            for (javax.servlet.http.Cookie cookie : request.getCookies()) {
                cookie.setMaxAge(0);
                cookie.setValue(null);
                cookie.setPath("/");
            }
            model.addAttribute(MESSAGE, "You have been logged out successfully.");
            model.addAttribute(SUCCESSMSG, true);
        }
    
        final ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("adminLogin", new AdminLogin());
        modelAndView.setViewName("login");
        return modelAndView;
    

    }

    【讨论】:

    • 我认为不需要指定控制器,因为注销已经在 Spring Security 中实现。如果我错了,请纠正我。
    • 是的,我已经提到了 Spring Security 和手动如何注销和清除会话、cookie 等
    猜你喜欢
    • 2011-05-08
    • 2013-04-05
    • 2014-10-01
    • 2012-09-06
    • 2017-11-16
    • 1970-01-01
    • 2020-04-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多