Java Spring安全:如何为未登录的用户关闭/注销?

Java Spring安全:如何为未登录的用户关闭/注销?,java,spring-boot,spring-security,thymeleaf,Java,Spring Boot,Spring Security,Thymeleaf,我正在构建一个spring安全应用程序。登录和注销工作正常,但我想让未登录的用户无法注销,这在默认情况下是可能的(奇怪…) 我试图为/logout添加一个自定义控制器(检查用户是否经过身份验证),但似乎没有任何效果。有没有办法在spring配置中实现这一点?下面是我的代码。控制器不工作。即使用户未经过身份验证,默认的spring安全/注销视图也是可见的 package com.example.demo.config; import com.example.demo.security.Custo

我正在构建一个spring安全应用程序。登录和注销工作正常,但我想让未登录的用户无法注销,这在默认情况下是可能的(奇怪…)

我试图为/logout添加一个自定义控制器(检查用户是否经过身份验证),但似乎没有任何效果。有没有办法在spring配置中实现这一点?下面是我的代码。控制器不工作。即使用户未经过身份验证,默认的spring安全/注销视图也是可见的

package com.example.demo.config;

import com.example.demo.security.CustomAccessDeniedHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public AccessDeniedHandler accessDeniedHandler() {
        return new CustomAccessDeniedHandler();
    }

    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/**").permitAll() // This will be your home screen URL
                .antMatchers("/css/**").permitAll()
                .antMatchers("/assets/css/js/**").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin().permitAll()
                .and()
                .exceptionHandling()
                .accessDeniedHandler(new CustomAccessDeniedHandler())
        ;
    }
}

-----------------
@RequestMapping("/logout")
    public String logout() {
        if (!(SecurityContextHolder
                .getContext()
                .getAuthentication()
                .getPrincipal() instanceof MyUserPrincipal)) {
//            System.out.println("Non logged user is trying to logout");
            return "redirect:/";
        } else {
//            System.out.println("Logged user is trying to logout");
            return "redirect:/logout";
        }
    }

您需要通过
configure
方法中的
WebSecurityConfig
类处理注销URL的权限,您已经在对某些URL执行此操作,因此更改为:

protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
            .antMatchers("/**").permitAll() // This will be your home screen URL
            .antMatchers("/css/**").permitAll()
            .antMatchers("/assets/css/js/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin().permitAll()
            .and()
            .logout()
                .logoutUrl("/logout")
                .logoutSuccessUrl("/logoutSuccessful")
                .permitAll()
                .deleteCookies("JSESSIONID")
                .invalidateHttpSession(true)
            .and()
            .exceptionHandling()
            .accessDeniedHandler(new CustomAccessDeniedHandler())
    ;
}
注意添加了

.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/logoutSuccessful")
.permitAll()
.deleteCookies("JSESSIONID")
.invalidateHttpSession(true)
这是我们的注销处理代码,因此如果用户点击
/logout
,他们将注销并转发到
/logoutSuccessful
(我通常会重定向到
登录
页面)

您还可以在此处添加一些其他方法来配置注销。注销与登录一样可配置,因此您可以根据需要添加注销处理程序


终于找到了解决办法。用户进入/注销后显示的“确定…”页面似乎由CSRF模块生成。翻开CSRF后,页面不再显示。但这不是解决方案,因为需要启用csrf以实现安全性。少了一行: .logoutRequestMatcher(新的AntPathRequestMatcher(“/logout”)) . 现在,用户在转到/注销后已注销,未询问任何问题。这不是我想要的解决方案,但它现在起作用了;)。谢谢大家的回复

package com.example.demo.config;

import com.example.demo.security.CustomAccessDeniedHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public AccessDeniedHandler accessDeniedHandler() {
        return new CustomAccessDeniedHandler();
    }

    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/**").permitAll() // This will be your home screen URL
                .antMatchers("/css/**").permitAll()
                .antMatchers("/assets/css/js/**").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin().permitAll()
                .and()
                .logout()
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                .logoutSuccessUrl("/login")
                .deleteCookies("JSESSIONID")
                .invalidateHttpSession(true)
                .and()
                .exceptionHandling()
                .accessDeniedHandler(new CustomAccessDeniedHandler())
        ;
    }
}

大家好,欢迎来到StackOverflow!你介意编辑你的帖子并向我们展示不起作用的代码吗?我想知道:你为什么关心没有登录的用户可以注销?当您已经注销时注销通常是不允许的。显然,注销视图必须对未经身份验证的用户可见:他们刚刚注销。@markrotVeel-感谢您的关注。在我的例子中,一个未经身份验证的用户gos to/logout url应用程序询问他是否想要注销(“你确定要注销吗?”+注销按钮),我认为这是默认的spring安全功能。我认为未经身份验证的用户不应该看到这一点,但却无法为他禁用这一点……您应该处理用户是否可以在
WebSecurityConfig configure
方法下访问注销页面。谢谢@Popeye。但这对我来说并不管用。“您确定…?”提示页面仍然可见,即使对于已注销的用户也是如此。我的应用程序使用数据库用户授权和CustomMethodSecurityExpressionHandler。也许这就是原因。仍在搜索…您将需要添加一个自定义注销处理程序,以检查是否有一个事先登录的用户,我相信。在这一点上很难说会是什么样子,所以我建议大家上网看看教程