简体   繁体   中英

Spring Security - Cannot login with custom login page

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...

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.

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");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM