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.