【问题标题】:Logout link with Spring and Thymeleaf; post error与 Spring 和 Thymeleaf 的注销链接;发布错误
【发布时间】:2019-03-22 22:09:50
【问题描述】:

以下问题:

我用 Spring 创建了一个简单的注销:

    <form th:action="@{/logout-custom}" method="POST" name="logoutForm" 
    id="logout">
        <input type="submit"/>
    </form>   

安全性:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .antMatchers("/cont/**").access("hasRole('USER')")
            .and()

            .formLogin()
            .loginPage("/login")
            .defaultSuccessUrl("/login-success", true)
            .failureUrl("/failLogin.html")
            .permitAll()

            .and()
            .logout().logoutUrl("/logout").permitAll()

        .and()
        .csrf()
        .disable();
}    

控制器:

//Logout
@RequestMapping(value="/logout-custom", method = RequestMethod.POST)
public RedirectView logoutPage (HttpServletRequest request, 
HttpServletResponse response) {
    Authentication auth = 
SecurityContextHolder.getContext().getAuthentication();
    if (auth != null){
        new SecurityContextLogoutHandler().logout(request, response, auth);
    }
    return new RedirectView("/loginForm.html");
}   
// redirecting to login Page

依赖关系:

               <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>


    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-jasper</artifactId>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-test</artifactId>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
    </dependency>

当我单击注销按钮时,它显示“不支持请求方法'POST'”错误。

使用方法 GET 它只是添加了一个“?”在我的网址后面签名没有显示错误也没有重定向。 我从我的 html 中删除了所有内容,除了表单,因为似乎有些脚本阻止了整个事情(这是后来的问题)。 我还尝试删除控制器并仅使用 logout().logoutUrl().logoutSuccessUrl() 但这也不起作用。

【问题讨论】:

  • 我知道。我认为这不必指向与控制器和注销表单相同的路径。可以?我只是试图将所有 3 点都指向注销自定义。同样的错误..
  • 日志中的确切异常是什么,根本原因?此消息可能属于 stacktrace 的最后一个异常。
  • @benjaminc 堆栈跟踪是:请求方法 'POST' 不支持 [nio-8080-exec-7] .wsmsDefaultHandlerExceptionResolver :由处理程序执行引起的已解决异常:org.springframework.web.HttpRequestMethodNotSupportedException:请求不支持方法“POST”
  • 你能发布你的 spring pom 依赖项吗?
  • @CrazySabbath 当然。

标签: java spring


【解决方案1】:

SecurityContextLogoutHandler是默认添加的,因此您无需为它实现自定义注销。

如果您想添加其他LogoutHandler,您可以在您的配置中进行:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .antMatchers("/cont/**").access("hasRole('USER')")
            .and()

            .formLogin()
            .loginPage("/login")
            .defaultSuccessUrl("/login-success", true)
            .failureUrl("/failLogin.html")
            .permitAll()

            .and()
            .logout().logoutUrl("/logout-custom")
            .logoutSuccessUrl("/login")
            .addLogoutHandler(new CustomLogoutHandler())
            .permitAll()

        .and()
        .csrf()
        .disable();
}

logoutSuccessUrl("/login") 将在用户成功注销后将用户重定向到登录。

更新: 另外删除 th: 并使用纯 HTML 就可以了。

【讨论】:

  • 我在你写的时候改变了它,但没有 CustomLogoutHandler。我将表单中的网址更改为 /logout ,但它仍然无法正常工作..
  • @temp 操作和配置的注销 url 必须匹配,所以我更新了答案
  • 我只是按照用户的建议做了下面的评论。即使是那个简单的解决方案也不起作用。我想我的表格可能有问题..你知道为什么吗?
  • @temp 你可以尝试使用链接而不是表单 注销
  • 哇哦,终于成功了!我也被注销了。也许百里香有错误?因为我尝试过: Logout 而不是普通链接,它不起作用。编辑:甚至在删除百里香后表格也可以工作!
【解决方案2】:

我已经有一段时间没有使用带有百里香的 spring 了,但我认为 RedirectView 必须指向一个 url。我自己试过你的例子,它确实没有用。然而,一些细微的变化使它起作用:

如果您的控制器中尚不存在用于登录的 url:

@GetMapping("/loginForm")
public String loginForm() {
    return "loginForm";
}

更改您的重定向视图:

return new RedirectView("/loginForm");

这是资源结构:

resources
  -> templates
    -> loginForm.html
    -> logout.html

【讨论】:

  • 好的,谢谢。但是我没有 logout.html 我在 home.html 上注销,这是上面的一个文件夹。
  • 并且更改 RedirectView("/login-success")(这是我的登录重定向)对我不起作用。
  • logout.html 没关系,这只是一个例子,因为我没有包含注销表单的 .html 文件。
【解决方案3】:

为什么使用.logout().logoutUrl("/logout").permitAll()

同时使用@RequestMapping(value="/logout-custom", method = RequestMethod.POST),应该是同一个URL

或者简单点

<form th:action="@{/logout}" method="post">
         <button type="submit">Sign Out</button>        
 </form>

并在安全配置使用。

   .logout().permitAll();

默认情况下已经存在注销功能。

【讨论】:

  • 当我像你说的那样做时,没有指定的注销页面?
  • 我按照你说的改了,但还是不行。我还尝试在我的控制器和表单上命名 URL,但这也没有改变任何东西。
  • 您的意思是,注销发生了,您需要在注销后显示页面?还是根本没有注销?
  • 我猜注销根本没有发生。它只是显示 POST 错误。
  • 试试我的解决方案并设置 .logoutSuccessUrl("/login");例如,它将引用登录页面
猜你喜欢
  • 2016-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-26
  • 2011-06-13
  • 1970-01-01
  • 1970-01-01
  • 2019-10-08
相关资源
最近更新 更多