Register form only works if user is already logged in

Tags: , , ,



I created a Spring Boot web application, and it is connected to a local MySQL database.

I have a template called “login.html” which has a login form, as well as a register form in it.

This is the template “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>

In the MySQL database, I have many users with an email address and password. With these credentials, I can login into my application without problems.

But the register form only works if the user is already logged in. When I view the /login page, and I want to register an account with the register form, and I click on the submit button, I will be redirected to the login page and nothing happens. The user will then not be registered and will not show in my database.

But when I first login with user credentials, and later on register a new user, it magically works and the user is registered and it shows in my database.

Here is the controller class “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";
    }
}

And here is the securityconfiguration class “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();
    }
}

Would be great if someone can help, sitting on this problem for a while.

Answer

The problem is that you haven’t included "/register" in the rule that defines paths that can be accessed unauthenticated (through permitAll()), so the .anyRequest().authenticated() rule applies, which requires the user to be authenticated.

To fix this, add "/register" to the antMatchers(...) list of the permitAll() rule.



Source: stackoverflow