I have two separate login forms, one for users and one for admins.
The problem is that Spring ignores the config paramter for loginProcessingUrl
, for the admin as well as for the user. Whenever I try to login, it gives me 404 error.
While I was using RequestMatchers()
, it worked perfectly but just for one of them (user or admin) but not both. So I switched to SecurityMatcher()
which does restrict the users from accessing any path such as /admin/**
or /user/**
without login but the problem is that the login is not working.
Can someone help me with this?
Config class:
package com.business.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import com.business.service.impl.UserDetailsServiceImpl;
@Configuration
@EnableWebSecurity
@Order(1)
public class SecurityConfiguration {
@Autowired
UserDetailsServiceImpl userDetailService;
@Bean
public static BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public DaoAuthenticationProvider authProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(userDetailService);
provider.setPasswordEncoder(passwordEncoder());
return provider;
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration)
throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
@Order(1)
public static class UserSecurityConfig {
@Bean
public SecurityFilterChain filterChain1(HttpSecurity http) throws Exception {
http
.securityMatcher("/user/**")
.authorizeHttpRequests()
.requestMatchers("/user/**").hasRole("ROLE_USER")
.and()
.formLogin()
.loginPage("/user-login")
.loginProcessingUrl("/userLogin")
.permitAll()
.usernameParameter("email")
.passwordParameter("password")
.defaultSuccessUrl("/user/home")
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/").and()
.exceptionHandling()
.accessDeniedPage("/403");
return http.build();
}
}
@Order(2)
public static class AdminSecurityConfig {
@Bean
public SecurityFilterChain filterChain2(HttpSecurity http) throws Exception {
http
.securityMatcher("/admin/**")
.authorizeHttpRequests()
.requestMatchers("/admin/**").hasRole("ROLE_ADMIN")
.and()
.formLogin()
.loginPage("/admin-login")
.loginProcessingUrl("/adminLogin")
.permitAll()
.usernameParameter("email")
.passwordParameter("password")
.defaultSuccessUrl("/admin/home")
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/")
.and()
.exceptionHandling()
.accessDeniedPage("/403");
return http.build();
}
}
@Order(3)
public static class GeneralSecurityConfig {
@Bean
public SecurityFilterChain filterChain3(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests()
.requestMatchers("/**").permitAll();
http
.csrf().disable()
.headers()
.frameOptions().disable();
return http.build();
}
}
}
Admin login page:
<!DOCTYPE html>
<html lang="en" xmlns:th="https://www.thymeleaf.org"
th:replace="~{base::layout(~{::section})}">
<head>
<meta charset="ISO-8859-1">
<title>Universal Education : Login</title>
</head>
<body>
<section>
<div >
<div >
<div >
<h3 >Admin Login</h3>
<div th:if="${register}" >
<h6 th:text="${register}" ></h6>
<th:block></th:block>
</div>
<!-- Pills navs -->
<ul id="ex1"
role="tablist">
<li role="presentation"><a
id="tab-login" data-mdb-toggle="pill"
href="#pills-login" role="tab" aria-controls="pills-login"
aria-selected="true">Login</a></li>
<li role="presentation"><a
id="tab-register" data-mdb-toggle="pill" href="/admin-register"
role="tab" aria-controls="pills-register" aria-selected="false">Register</a>
</li>
</ul>
<!-- Pills navs -->
<div th:if="${param.error}" >Invalid Email
and Password</div>
<div th:if="${param.logout}" >
Successfully Logged Out</div>
<!-- Pills content -->
<div >
<div id="pills-login"
role="tabpanel" aria-labelledby="tab-login">
<form th:action="@{/adminLogin}" method="post">
<!-- Email input -->
<div >
<input type="email" id="loginName"
name="email" /> <label for="loginName">Email</label>
</div>
<!-- Password input -->
<div >
<input type="password" id="loginPassword"
name="password" /> <label
for="loginPassword">Password</label>
</div>
<!-- 2 column grid layout -->
<div >
<div >
<!-- Submit button -->
<button type="submit" >Sign
in</button>
</div>
<div >
<!-- Simple link -->
<a href="#!">Forgot password?</a>
</div>
<!-- Register buttons -->
<p>
Not a member? <a th:href="@{/user-register}">Register</a>
</p>
</div>
</form>
</div>
</div>
<!-- Pills content -->
</div>
</div>
</div>
</section>
</body>
</html>
Screenshot :
This is what I get when I try to login
CodePudding user response:
I had followed the same tutorial link you posted in the comments. I encountered similar issues and came to a resolution by combining that tutorial with this second one Multiple Login Pages
Essentially, I kept both static classes in the SecurityConfig file as described by the baeldung tutorial but instead of configuring a SecurityFilterChain I used the configure method to establish both logins.