首页 > 解决方案 > 注册表仅在用户已登录时才有效

问题描述

我创建了一个 Spring Boot Web 应用程序,它连接到本地 MySQL 数据库。

我有一个名为“login.html”的模板,其中有一个登录表单以及一个注册表单。

这是模板“login.html”:

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

<head>
    <meta charset="ISO-8859-1">
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <script src="https://kit.fontawesome.com/64d58efce2.js" crossorigin="anonymous"></script>
    <link rel="stylesheet" type="text/css" href=../static/css/styles.css th:href="@{/css/styles.css}">
    <!--<link rel="stylesheet" 
    href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"  integrity="sha384- 
    BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
          crossorigin="anonymous">-->

    <title>Be or become a Member</title>
</head>

<body>
    <header class="header">
    <a href="#" th:href="@{/}" class="logo">Mreza Mladih</a>
    <input class="menu-btn" type="checkbox" id="menu-btn"/>
    <label class="menu-icon" for="menu-btn"><span class="nav-icon"></span></label>
    <ul class="menu">

        <li><a href="/login">Login</a></li>
        <li><a href="Impressum.html" th:href="@{/impressum}">Impressum</a></li>
        <li><a href="">Instagram</a></li>
        <li><a href="file:///C:/Users/malik/Desktop/projekte/MM%20Seite%202/shop2/shop2.html">Shop</a> 
    </li>
        <li><a href="file:///C:/Users/malik/Desktop/projekte/MM%20Seite%202/contact.html">Contact</a> 
    </li>
    </ul>
    </header>

    <div class="containerLOGSIGN">
    <div class="forms-containerLOGSIGN">
        <div class="signin-signupLOGSIGN">
            <form name="login" action="login" th:action="@{/login}" method="post" class="sign-in- 
            formLOGSIGN">

                <!--error message-->
                <div th:if="${param.error}">
                    <div class="alert alert-danger">Invalid username or
                        password.
                    </div>
                </div>

                <!--logout message-->
                <div th:if="${param.logout}">
                    <div class="alert alert-info">You have been logged out.</div>
                </div>

                <h2 class="titleLOGSIGN">Sign in</h2>

                <div class="input-fieldLOGSIGN">
                    <i class="fas fa-user"></i>
                    <input type="text" placeholder="Username" autofocus="autofocus" name="username"/>
                </div>

                <div class="input-fieldLOGSIGN">
                    <i class="fas fa-lock"></i>
                    <input type="password" placeholder="Password" name="password"/>
                </div>

                <input type="submit" value="Login" class="btn solid" name="login-submit"/>
                <p class="social-textLOGSIGN">Or Sign in with social platforms</p>
                <div class="social-mediaLOGSIGN">
                    <a href="#" class="social-iconLOGSIGN">
                        <i class="fab fa-facebook-f"></i>
                    </a>
                    <a href="#" class="social-iconLOGSIGN">
                        <i class="fab fa-twitter"></i>
                    </a>
                    <a href="#" class="social-iconLOGSIGN">
                        <i class="fab fa-google"></i>
                    </a>
                    <a href="#" class="social-iconLOGSIGN">
                        <i class="fab fa-linkedin-in"></i>
                    </a>
                </div>
            </form>

            <!-- success message -->
            <div th:if="${param.success}">
                <div class="alert alert-info">You've successfully registered
                    to our awesome app!
                </div>
            </div>


            <form name="register" action="register" th:action="@{/register}" method="post" 
            th:object="${user}" class="sign-up-formLOGSIGN">
                <h2 class="titleLOGSIGN">Sign up</h2>

                <div class="input-fieldLOGSIGN">
                    <i class="fas fa-user"></i>
                    <input type="text" placeholder="FirstName" th:field="*{firstName}" required 
                autofocus="autofocus"/>
                </div>

                <div class="input-fieldLOGSIGN">
                    <i class="fas fa-user"></i>
                    <input type="text" placeholder="LastName" th:field="*{lastName}" required 
                autofocus="autofocus"/>
                </div>

                <div class="input-fieldLOGSIGN">
                    <i class="fas fa-envelope"></i>
                    <input type="email" placeholder="Email" th:field="*{email}" required 
                autofocus="autofocus"/>
                </div>

                <div class="input-fieldLOGSIGN">
                    <i class="fas fa-lock"></i>
                    <input type="password" placeholder="Password" th:field="*{password}" required
                           autofocus="autofocus"/>
                </div>

                <div class="input-fieldLOGSIGN">
                    <i class="fas fa-lock"></i>
                    <input type="text" placeholder="Dzemat" th:field="*{dzemat}" required 
               autofocus="autofocus"/>
                </div>

                <input type="submit" class="btnLOGSIGN" value="Sign up">


                <p class="social-textLOGSIGN">Or Sign up with social platforms</p>
                <div class="social-mediaLOGSIGN">
                    <a href="#" class="social-iconLOGSIGN">
                        <i class="fab fa-facebook-f"></i>
                    </a>
                    <a href="#" class="social-iconLOGSIGN">
                        <i class="fab fa-twitter"></i>
                    </a>
                    <a href="#" class="social-iconLOGSIGN">
                        <i class="fab fa-google"></i>
                    </a>
                    <a href="#" class="social-iconLOGSIGN">
                        <i class="fab fa-linkedin-in"></i>
                    </a>
                </div>
            </form>
        </div>
    </div>

    <div class="panels-containerLOGSIGN">
        <div class="panel left-panel">
            <div class="contentLOGSIGN">
                <h3>New here ?</h3>
                <p>
                    Sign up to become a Mreza Mladih Member. Join us!
                </p>
                <button class="btn transparent" id="sign-up-btn">
                    Sign up
                </button>
            </div>
            <img src="../static/img/MrezaMladih_klein_neu.PNG" th:src="@{/img/MrezaMladih_klein_neu.PNG}" 
            class="image" alt=""/>
        </div>
        <div class="panel right-panel">
            <div class="contentLOGSIGN">
                <h3>Already a member?</h3>
                <p>
                    Sign in with your email and your passcode!
                </p>
                <button class="btn transparent" id="sign-in-btn">
                    Sign in
                </button>
            </div>
        </div>
    </div>
</div>

<script type="text/javascript" src="../static/js/login2.js" th:src="@{/js/login2.js}"></script>
</body>

</html>

在 MySQL 数据库中,我有许多具有电子邮件地址和密码的用户。使用这些凭据,我可以毫无问题地登录我的应用程序。

但是注册表只有在用户已经登录时才有效。当我查看/login页面时,我想用注册表注册一个帐户,然后单击提交按钮,我将被重定向到登录页面,什么也没有发生。用户将不会被注册,也不会显示在我的数据库中。

但是当我第一次使用用户凭据登录,然后注册一个新用户时,它神奇地工作并且用户已注册并显示在我的数据库中。

这是控制器类“UserRegistrationController.java”:

package com.example.springboot_web_app_with_login.web;

import com.example.springboot_web_app_with_login.model.User;
import com.example.springboot_web_app_with_login.service.UserService;
import com.example.springboot_web_app_with_login.web.dto.UserRegistrationDto;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
        
@Controller
public class UserRegistrationController {

    private UserService userService;

    public UserRegistrationController(UserService userService) {
        super();
        this.userService = userService;
    }

    // Hierdurch wird dem Register Formular der User mitgeliefert
    @ModelAttribute("user")
    public UserRegistrationDto userRegistrationDto() {
        return new UserRegistrationDto();
    }

    // Die Get Methode für die Login Seite
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String login(Model model) {

        model.addAttribute("login", new User());
        model.addAttribute("register", new UserRegistrationDto());
        return "login";
    }


    // Die POST Methode für das Register Form
    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public String registerUserAccount(@ModelAttribute("user") UserRegistrationDto registrationDto, Model model) {
        model.addAttribute("register", new UserRegistrationDto());
        userService.save(registrationDto);
        return "redirect:login?success";
    }
}

这是安全配置类“SecurityConfiguration.java”:

package com.example.springboot_web_app_with_login.config;

import com.example.springboot_web_app_with_login.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider auth = new DaoAuthenticationProvider();
        auth.setUserDetailsService(userService);
        auth.setPasswordEncoder(passwordEncoder());
        return auth;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.
                authorizeRequests()
                //Hier werden alle Seiten aufgeführt, die dem User zugänglich sind,also "permit"
                .antMatchers("/login", "/js/**", "/css/**", "/countryPages/**", "/img/**", "/", "/impressum").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login")
                /*.loginProcessingUrl("/login")*/
                .defaultSuccessUrl("/", true)
                .permitAll()
                .and()
                .logout()
                .invalidateHttpSession(true)
                .clearAuthentication(true)
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                .logoutSuccessUrl("/login?logout")
                .permitAll();
    }
}

如果有人可以帮助解决这个问题,那就太好了。

标签: javamysqlspring-bootauthentication

解决方案


问题是您没有包含"/register"在定义可以未经身份验证(通过permitAll())访问的路径的规则中,因此该.anyRequest().authenticated()规则适用,这需要对用户进行身份验证。

要解决此问题,请添加"/register"到规则antMatchers(...)列表。permitAll()


推荐阅读