首页 > 解决方案 > Thymeleaf 多次调用登录页面(spring boot)

问题描述

Structure

java
-example
--controller
---LoginController
--security
---SecurityConfig

resources
-templates
--landingpage
---login.html
--about.html

这是控制器

    @Controller
    public class LoginController {

        @GetMapping("/login")
        public String login()
        {


            return "landingpage/login";
        }

   @RequestMapping("/about")
    public String about() {
        return "about";
    }

    }

这是安全配置

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers(
                        "/",
                        "/js/**",
                        "/css/**",
                        "/img/**",
                        "/webjars/**").permitAll()
                .antMatchers("/user/**").hasRole("USER")
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login")
                .permitAll();
//                .and()
//                .logout()
//                .invalidateHttpSession(true)
//                .clearAuthentication(true)
//                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
//                .logoutSuccessUrl("/login?logout")
//                .permitAll()
//                .and()
//                .exceptionHandling()
//                .accessDeniedHandler(accessDeniedHandler);
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("user").password("password").roles("USER")
                .and()
                .withUser("manager").password("password").roles("MANAGER");
    }

}

这是登录html

<!DOCTYPE html>
<html lang="tr" xmlns:th="http://www.thymeleaf.org">
<head>

</head>
<body class="login-page">
    <div class="login-container">
        <div class="login-branding">
            <a href="/dashboard"><img src="../../static/images/logo.png" alt="Clevex" title="Clevex"></a>
        </div>
        <div class="login-content">
            <h2><strong>Welcome</strong>, please login</h2>

            <form th:action="@{/login}" method="post">
                <div class="form-group">
                    <input type="text" placeholder="Username" class="form-control">
                </div>
                <div class="form-group">
                    <input type="password" placeholder="Password" class="form-control">
                </div>

                <div class="form-group">
                    <button class="btn btn-primary btn-block">Login</button>
                </div>
                <p class="text-center"><a href="/forgot-password">Forgot your password?</a></p>
            </form>
            <p><a href="/" th:href="@{/}">Back to home page</a></p>
        </div>
    </div>

    <!--Load JQuery-->
    <script src="../../static/js/jquery.min.js"></script>
    <script src="../../static/js/bootstrap.min.js"></script>
</body>
</html>

我去 http://localhost:8080/login

它显示了我的登录页面。它显示登录表单,但在控制台中,我看到了这些错误

拒绝从 ' http://localhost:8080/login ' 执行脚本,因为它的 MIME 类型 ('text/html') 不可执行,并且启用了严格的 MIME 类型检查。login:1 [DOM] 输入元素应具有自动完成属性(建议:“current-password”):(更多信息:https)​</p>

当我打开调试模式并刷新时,它会调用/login端点 6 次,然后带来登录表单。

当我输入错误的用户名/密码并点击提交时,它会调用登录 5 次。对于userand password(在 securityconfig 中定义),它调用了 6 次,但不能转到abouthtml.

对于错误或真实的用户名 - 密码,它会重定向到 http://localhost:8080/login?error

当我去 http://localhost:8080

它调用登录端点 1 次然后显示空白页。

在控制台中没有错误。

这是 pomxml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>

    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>nz.net.ultraq.thymeleaf</groupId>
            <artifactId>thymeleaf-layout-dialect</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
            <version>3.0.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </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-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- Spring Security -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <!-- do you like thymeleaf? -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <!-- optional, it brings userful tags to display spring security stuff -->
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity4</artifactId>
        </dependency>

        <!-- hot swapping, disable cache for template, enable live reload -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring5</artifactId>
            <version>3.0.11.RELEASE</version>
        </dependency>

        <!-- Optional, for bootstrap -->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>3.3.7</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

我想要的是简单的登录表单。使用inMemoryAuthentication,我定义了用户和密码。它应该about.html在使用该凭据成功登录后进入,但它不能去。

因为manager也一样。

我试图禁用 securityconfig,一些antmatchers.

https://memorynotfound.com/spring-boot-spring-security-thymeleaf-form-login-example/

这也和我一样,但还是一样。

为什么会多次调用?

标签: springspring-bootthymeleaf

解决方案


我想问题是您没有在 Spring Security 设置中指定 loginProcessingUrl 。使用 loginProcessingUrl("/authenticateTheUser") 方法,然后将 POST 请求发送到指定的指定 URL。

<form th:action="@{/authenticateTheUser}" method="post">

此类设置的示例

http
            .authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .and()
            .formLogin()
            .loginPage("/login")
            .loginProcessingUrl("/authenticateTheUser")
            .permitAll()
            .and()
            .logout()
            .logoutSuccessUrl("/")
            .permitAll();

推荐阅读