我正在为我的应用程序实现身份验证机制。 因此,如果用户是管理员并且提供了正确的用户名和密码,则应该对用户进行身份验证并向管理员显示主页。但就我而言,即使提供了正确的用户名和密码,即使在这种情况下,控件也会重定向到登录页面而不是主页。
以下是更多详情:-
登录页面:-
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Login & Registration Form | CoderGirl</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<input type="checkbox" id="check">
<div class="login form">
<header>Login</header>
<form action="/home" method="POST">
<input type="text" name="username" placeholder="Enter your email" required>
<input type="password" name="password" placeholder="Enter your password" required>
<a href="#">Forgot password?</a>
<input type="submit" class="button" value="Login">
</form>
<div class="signup">
<span class="signup">Don't have an account?
<label for="check">Signup</label>
</span>
</div>
</div>
<div class="registration form">
<header>Signup</header>
<form action="/register" method="POST">
<input type="text" name="username" placeholder="Enter your email" required>
<input type="password" name="password" placeholder="Create a password" required>
<input type="password" name="confirmPassword" placeholder="Confirm your password" required>
<input type="submit" class="button" value="Signup">
</form>
<div class="signup">
<span class="signup">Already have an account?
<label for="check">Login</label>
</span>
</div>
</div>
</div>
</body>
</html>
主页:-
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Product Management</title>
<link rel="stylesheet" href="home_style.css">
</head>
<body>
<div class="container">
<h1>Welcome to the Product Management System</h1>
<div class="button-container">
<button class="action-button" onclick="window.location.href='/add-product'">Add Product</button>
<button class="action-button" onclick="window.location.href='/remove-product'">Remove Product</button>
<button class="action-button" onclick="window.location.href='/modify-product'">Modify Product</button>
<button class="action-button" onclick="window.location.href='/view-product'">View Product</button>
</div>
<a href="/logout" class="logout-button">Logout</a>
</div>
</body>
</html>
控制器:-
@Controller
public class LoginController {
@Autowired
private UserService userService;
@Autowired
private CustomUserDetailsService customservice;
@Autowired
private PasswordEncoder passwordEncoder;
@GetMapping("/login")
public String loginPage() {
return "index"; // Render the login.html page
}
@GetMapping("/logout")
public String logoutPage() {
return "index"; // Render the logout.html page
}
@PostMapping("/home")
public String login(@RequestParam String username, @RequestParam String password) {
// Retrieve user from the database
System.out.println("login endpoint");
User user = userService.findByUsername(username);
Iterator<Role> iterator = user.getRoles().iterator();
while (iterator.hasNext()) {
Role fruit = iterator.next();
System.out.println(fruit.getRoleName());
}
if (user != null && passwordEncoder.matches(password, user.getPassword())) {
System.out.println("authentication complete");
return "home"; // Password matches, redirect to home
} else {
System.out.println("authentication incomplete");
return "index"; // Invalid login, return to login page
}
}
}
这是我的安全配置:-
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Autowired
private CustomUserDetailsService customUserDetailsService; // Inject the custom user details service
@Bean
public PasswordEncoder passwordEncoder() {
System.out.println("inside password encoder");
return new BCryptPasswordEncoder(); // Passwords should be hashed using BCrypt
}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
System.out.println("inside authentication provider");
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(customUserDetailsService); // Use injected CustomUserDetailsService
authProvider.setPasswordEncoder(passwordEncoder()); // Set password encoder
return authProvider;
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
System.out.println("inside authentication manager");
return authenticationConfiguration.getAuthenticationManager();
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
System.out.println("inside securityFilterChain");
http
.authorizeHttpRequests()
.requestMatchers("/css/**", "/js/**", "/images/**", "/static/**").permitAll()
.requestMatchers("/login", "/register", "*.css").permitAll() // Public access to login and register
.requestMatchers("/add-product", "/modify-product", "/remove-product").hasRole("ADMIN") // Restrict product modification to ADMIN roles
.requestMatchers("/view-product").authenticated() // Requires users to be authenticated
.anyRequest().authenticated() // All other requests need to be authenticated
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/home", true) // Redirect to home after login
.failureUrl("/login")
.and()
.logout()
.logoutSuccessUrl("/logout") // Redirect after logout
.permitAll()
.and()
.sessionManagement() // Configure session management
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) // Default policy
.maximumSessions(1) // Limit the number of concurrent sessions per user
.expiredUrl("/login?expired") // Redirect to login page if session expires
.and()
.and()
.csrf().disable(); // Disable CSRF for non-browser clients or API access
return http.build();
}
}
自定义用户详细服务:-
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
public CustomUserDetailsService() {
System.out.println("CustomUserDetailsService has been initialized.");
}
// Map roles to authorities, adding 'ROLE_' prefix
private Collection<? extends GrantedAuthority> mapRolesToAuthorities(Collection<Role> roles) {
return roles.stream()
.map(role -> new SimpleGrantedAuthority(role.getRoleName()))
.collect(Collectors.toList());
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
System.out.println("inside loaduserbyusername custom user");
User user = userRepository.findByUsername(username);
System.out.println("User is "+user.getUsername() +" and password is "+user.getPassword());
if (user == null) {
throw new UsernameNotFoundException("User not found");
}
org.springframework.security.core.userdetails.User springUser = new org.springframework.security.core.userdetails.User(
user.getUsername(),
user.getPassword(),
mapRolesToAuthorities(user.getRoles())
);
System.out.println("Spring Security User Details: ");
System.out.println("Username: " + springUser.getUsername());
System.out.println("Password: " + springUser.getPassword());
System.out.println("Authorities: " + springUser.getAuthorities());
return springUser;
}
}
日志:-
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.1.0)
2024-10-26T20:07:44.105+05:30 INFO 19060 --- [ restartedMain] com.example.webapp.Dia1Application : Starting Dia1Application using Java 17.0.3 with PID 19060 (C:\Users\Admin\eclipse-workspace\dia-1\target\classes started by Admin in workspace\dia-1)
2024-10-26T20:07:44.162+05:30 INFO 19060 --- [ restartedMain] com.example.webapp.Dia1Application : No active profile set, falling back to 1 default profile: "default"
2024-10-26T20:07:44.458+05:30 INFO 19060 --- [ restartedMain] o.s.b.devtools.restart.ChangeableUrls : The Class-Path manifest attribute in C:\Users\Admin\.m2\repository\com\oracle\database\jdbc\ojdbc8\19.8.0.0\ojdbc8-19.8.0.0.jar referenced one or more files that do not exist: file:/C:/Userscom/oracle/database/jdbc/ojdbc8/19.8.0.0/oraclepki.jar
2024-10-26T20:07:44.459+05:30 INFO 19060 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2024-10-26T20:07:44.460+05:30 INFO 19060 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2024-10-26T20:07:47.352+05:30 INFO 19060 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2024-10-26T20:07:47.948+05:30 INFO 19060 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 367 ms. Found 3 JPA repository interfaces.
2024-10-26T20:07:51.595+05:30 INFO 19060 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2024-10-26T20:07:51.642+05:30 INFO 19060 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2024-10-26T20:07:51.643+05:30 INFO 19060 --- [ restartedMain] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.8]
2024-10-26T20:07:51.957+05:30 INFO 19060 --- [ restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2024-10-26T20:07:51.959+05:30 INFO 19060 --- [ restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 7497 ms
2024-10-26T20:07:52.995+05:30 INFO 19060 --- [ restartedMain] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
2024-10-26T20:07:53.414+05:30 INFO 19060 --- [ restartedMain] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.2.2.Final
2024-10-26T20:07:53.428+05:30 INFO 19060 --- [ restartedMain] org.hibernate.cfg.Environment : HHH000406: Using bytecode reflection optimizer
2024-10-26T20:07:54.294+05:30 INFO 19060 --- [ restartedMain] o.h.b.i.BytecodeProviderInitiator : HHH000021: Bytecode provider name : bytebuddy
2024-10-26T20:07:55.194+05:30 INFO 19060 --- [ restartedMain] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer
2024-10-26T20:07:55.295+05:30 INFO 19060 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2024-10-26T20:07:56.818+05:30 INFO 19060 --- [ restartedMain] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection oracle.jdbc.driver.T4CConnection@567f88b3
2024-10-26T20:07:56.826+05:30 INFO 19060 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2024-10-26T20:07:58.454+05:30 INFO 19060 --- [ restartedMain] org.hibernate.orm.dialect : HHH035001: Using dialect: org.hibernate.dialect.OracleDialect, version: 21.0
2024-10-26T20:07:59.957+05:30 INFO 19060 --- [ restartedMain] o.h.b.i.BytecodeProviderInitiator : HHH000021: Bytecode provider name : bytebuddy
2024-10-26T20:08:04.301+05:30 INFO 19060 --- [ restartedMain] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2024-10-26T20:08:04.329+05:30 INFO 19060 --- [ restartedMain] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
CustomUserDetailsService has been initialized.
inside password encoder
2024-10-26T20:08:06.758+05:30 WARN 19060 --- [ restartedMain] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
inside authentication provider
inside securityFilterChain
2024-10-26T20:08:07.257+05:30 INFO 19060 --- [ restartedMain] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page template: index
2024-10-26T20:08:08.083+05:30 INFO 19060 --- [ restartedMain] o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@7beeb809, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@1250ad26, org.springframework.security.web.context.SecurityContextHolderFilter@f1c53e8, org.springframework.security.web.header.HeaderWriterFilter@5e21c003, org.springframework.security.web.authentication.logout.LogoutFilter@6af304cf, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@47bc56f1, org.springframework.security.web.session.ConcurrentSessionFilter@576c970f, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@2ad56bcf, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@5378e4fd, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@377e7a43, org.springframework.security.web.session.SessionManagementFilter@1454bc00, org.springframework.security.web.access.ExceptionTranslationFilter@7b40484, org.springframework.security.web.access.intercept.AuthorizationFilter@107f250f]
inside authentication manager
2024-10-26T20:08:09.118+05:30 INFO 19060 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2024-10-26T20:08:09.257+05:30 INFO 19060 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2024-10-26T20:08:09.300+05:30 INFO 19060 --- [ restartedMain] com.example.webapp.Dia1Application : Started Dia1Application in 27.13 seconds (process running for 30.667)
Hibernate: select r1_0.role_id,r1_0.role_name from roles r1_0 where r1_0.role_name=?
Hibernate: select u1_0.user_id,u1_0.password,u1_0.user_name from users u1_0 where u1_0.user_name=?
Hibernate: select r1_0.user_id,r1_1.role_id,r1_1.role_name from user_roles r1_0 join roles r1_1 on r1_1.role_id=r1_0.role_id where r1_0.user_id=?
2024-10-26T20:08:29.660+05:30 INFO 19060 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2024-10-26T20:08:29.661+05:30 INFO 19060 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2024-10-26T20:08:29.671+05:30 INFO 19060 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 7 ms
2024-10-26T20:08:29.708+05:30 DEBUG 19060 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Securing POST /home
2024-10-26T20:08:29.747+05:30 DEBUG 19060 --- [nio-8080-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2024-10-26T20:08:29.887+05:30 DEBUG 19060 --- [nio-8080-exec-1] o.s.s.w.s.HttpSessionRequestCache : Saved request http://localhost:8080/home?continue to session
2024-10-26T20:08:29.892+05:30 DEBUG 19060 --- [nio-8080-exec-1] o.s.s.web.DefaultRedirectStrategy : Redirecting to http://localhost:8080/login
2024-10-26T20:08:29.974+05:30 DEBUG 19060 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Securing GET /login
2024-10-26T20:08:29.975+05:30 DEBUG 19060 --- [nio-8080-exec-2] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2024-10-26T20:08:29.981+05:30 DEBUG 19060 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Secured GET /login
2024-10-26T20:08:31.829+05:30 DEBUG 19060 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : Securing GET /style.css
2024-10-26T20:08:31.829+05:30 DEBUG 19060 --- [nio-8080-exec-3] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2024-10-26T20:08:31.866+05:30 DEBUG 19060 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : Secured GET /style.css
角色表详细信息:-
ROLE_ID ROLE_NAME
1 ROLE_ADMIN
因此,我也在 loaduserbyusername 中添加了日志,但这些日志在应用程序启动期间或成功登录时不会生成。谁能帮忙看看出了什么问题。
您在登录页面的第
<form action="/home" method="POST">
行中出现错误。您需要将用户名和密码发送至/login
。