2

I am learning spring and I am currently learning traditional user / password authentication with Spring Security.

At the moment, if I let Spring use a default page to login, I can do it without any problems, but if I try to set a custom page for login, even typing the correct data (something I confirmed using the Inspect tool) , I am not redirected to the main page, but to the same login page, but instead of "localhost: 1812/login" the page changes to "localhost: 1812/login?error" and I am unable to login. Basically, my WebSecurityConfig class is:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        System.out.println("ccc");
        http
        .authorizeRequests()
        .anyRequest().authenticated()
        .and()
        //.formLogin().permitAll()
        .formLogin().loginPage("/login").permitAll()
        .defaultSuccessUrl("/home", true);
    
        System.out.println("ddd");
    
    }
    
    @Bean
    @Override
    protected UserDetailsService userDetailsService() {  
        System.out.println("AAA");
        UserDetails user = User.withDefaultPasswordEncoder()
                .username("root")
                .password("root")
                .roles("ADM")
                .build();
        System.out.println("bbb");
        return new InMemoryUserDetailsManager(user);
    }
}

If I use ".formLogin().permitAll()" instead of ".formLogin().loginPage("/login").permitAll()", I can successfully log in, but Spring will load a standard login page. I wanted to understand what could be wrong. On the Inspect tool I received the HTTP status code 302 when sending the login on the custom page, but I don't know what that means ... Here I leave the code for my LoginController and login.html, and if someone helps me I would be grateful too much because I tried hard and I couldn't solve the problem ...

LoginController

@Controller
public class LoginController {
    
    @GetMapping
    @RequestMapping("/login")
    public String login() {
        return "login";
    }
    
}

login.html

<!DOCTYPE html>
<html>
    <head th:replace="~{base :: head}"></head>
    <body>
        <div th:replace="~{base :: logo}"></div>
        <div class="container">
            <div th:replace="~{base :: titulo('Login')}"></div>
            <div class="card mb-3">
                <form th:action="@{/login}" method="POST" class="card-body">
                    <div class="form-group mb-3">
                        <div class="mb-2">
                            <label for="username" class="sr-only">Usuário</label>
                            <input type="text" name="username" class="form-control" placeholder="usuário"/>
                        </div>
                        <div class="mb-2">
                            <label for="password" class="sr-only">Senha</label>
                            <input type="password" name="username" class="form-control" placeholder="senha"/>
                        </div>
                        <button class="btn btn-primary" type="submit">Login</button>
                    </div>                  
                </form>
            </div>
        </div>
    </body>
</html>

Edit: With help of the user @Random Guy and some searching in the Google, I modifed my configure method to this:

protected void configure(HttpSecurity http) throws Exception {
        
        http
        .antMatcher("/**")
        .authorizeRequests()
          .antMatchers("/", "/login**","/callback/", "/webjars/**", "/css**", "/error**")
          .permitAll()
        .anyRequest()
          .authenticated()
         .and()
         .formLogin().loginPage("/login").loginProcessingUrl("/login")
         .defaultSuccessUrl("/home").failureUrl("/login?message=error").usernameParameter("username")
         .passwordParameter("password").and().logout().logoutUrl("/perform_logout")
         .logoutSuccessUrl("/login?message=logout");

}

But while still login not working, when I input the username and password, i'm redirectionated to same login page but with the url now is "http://localhost:1812/login?message=error", like in the line of code with ".failureUrl("/login?message=error")". Does this mean that my problem is in the html? Sincerely, I have no idea...

Edit 2: Using code from Display error messages in Spring login

to try to find what type of error I getting, my login method now is:

@GetMapping("/login-error")
    @RequestMapping("/login")
    public String login(HttpServletRequest request, Model model) {
        HttpSession session = request.getSession(false);
        String errorMessage = null;
        if (session != null) {
            AuthenticationException ex = (AuthenticationException) session
                    .getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
            if (ex != null) {
                errorMessage = ex.getMessage();
            }
        }
        System.out.println("--->" + errorMessage);
        model.addAttribute("errorMessage", errorMessage);
        return "login";
    }

And, again, even typing the correct credentials, as I specified in the "userDetailsService" method, I can't log in, but this time I can finally see the error message on the console:

--->User not found or invalid password

Apparently I walked but without leaving the place, since right now I have no ideia what could be wrong with my code...

2 Answers 2

2

Looks like this might just be a typo. Your password field is called username:

<input type="password" name="username" class="form-control" placeholder="senha"/>

change it to:

<input type="password" name="password" class="form-control" placeholder="senha"/>

and all is well.

Sign up to request clarification or add additional context in comments.

2 Comments

man, oh man. I just don't throw my diploma away, because that kind of mistake is really common when we program, but I feel so dumb when I realize that I spent a whole day trying to solve the problem where it was just a variable name error .... ... anyway, I am immensely grateful that you noticed this error :)
Quite welcome! Good luck with next steps.
0

You need to add some code like this to config username and password from your form, and also use loginProcessingUrl() – the URL to submit the username and password to.

The default URL where the Spring Login will POST to trigger the authentication process is /perform_login, which used to be /j_spring_security_check before Spring Security 4.

Reference resource: reference resource

@Override
protected void configure(HttpSecurity http) throws Exception {
    // Redirect to 403 page if user do not has role permission
    http.authorizeRequests().and().exceptionHandling().accessDeniedPage("/403");
    // Login & Logout cofig
    http.authorizeRequests().and().formLogin().loginPage("/login").loginProcessingUrl("/perform_login")
            .defaultSuccessUrl("/home").failureUrl("/login?message=error").usernameParameter("username")
            .passwordParameter("password").and().logout().logoutUrl("/perform_logout")
            .logoutSuccessUrl("/login?message=logout");
}

1 Comment

thanks for helping! But when I used your code for configure method I was blessed with this exception: " java.lang.IllegalStateException: At least one mapping is required (i.e. authorizeRequests().anyRequest().authenticated())", so, I added the code suggested by the error and my Chrome says: "this page is not working. Too many redirects from localhost"...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.