JSP 整合 Spring Security 实现登录认证示例
随着互联网技术的不断发展,Web应用程序的安全问题日益突出。为了确保Web应用程序的安全性,登录认证是必不可少的环节。本文将围绕JSP(JavaServer Pages)语言,结合Spring Security框架,实现一个简单的登录认证示例。通过本文的学习,读者可以了解到JSP与Spring Security的整合方法,以及如何实现基本的用户认证和授权。
环境准备
在开始之前,我们需要准备以下环境:
1. JDK 1.8 或更高版本
2. Maven 3.0 或更高版本
3. IntelliJ IDEA 或其他Java IDE
4. Tomcat 9.0 或更高版本
项目结构
以下是项目的目录结构:
src/
|-- main/
| |-- java/
| | |-- com/
| | | |-- example/
| | | | |-- controller/
| | | | | |-- LoginController.java
| | | | |-- security/
| | | | | |-- WebSecurityConfig.java
| | | | |-- model/
| | | | | |-- User.java
| | | | |-- service/
| | | | | |-- UserService.java
| | | | |-- repository/
| | | | | |-- UserRepository.java
| |-- resources/
| | |-- application.properties
| |-- webapp/
| |-- WEB-INF/
| | |-- views/
| | | |-- login.jsp
| | | |-- index.jsp
| |-- index.jsp
|-- pom.xml
1. 创建项目
使用Maven创建一个Java Web项目,并添加以下依赖:
xml
<dependencies>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Starter Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- Thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- MySQL Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
2. 配置数据库
在`application.properties`文件中配置数据库连接信息:
properties
spring.datasource.url=jdbc:mysql://localhost:3306/example_db?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=update
3. 创建实体类
在`model/User.java`文件中创建用户实体类:
java
package com.example.model;
import javax.persistence.;
import java.util.Set;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(unique = true)
private String username;
private String password;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(
name = "user_roles",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id")
)
private Set<Role> roles;
// Getters and setters...
}
在`model/Role.java`文件中创建角色实体类:
java
package com.example.model;
import javax.persistence.;
import java.util.Set;
@Entity
@Table(name = "roles")
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(unique = true)
private String name;
@ManyToMany(mappedBy = "roles")
private Set<User> users;
// Getters and setters...
}
4. 创建数据访问层
在`repository/UserRepository.java`文件中创建用户数据访问接口:
java
package com.example.repository;
import com.example.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
User findByUsername(String username);
}
在`repository/RoleRepository.java`文件中创建角色数据访问接口:
java
package com.example.repository;
import com.example.model.Role;
import org.springframework.data.jpa.repository.JpaRepository;
public interface RoleRepository extends JpaRepository<Role, Long> {
}
5. 创建业务逻辑层
在`service/UserService.java`文件中创建用户业务逻辑类:
java
package com.example.service;
import com.example.model.User;
import com.example.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private PasswordEncoder passwordEncoder;
public User saveUser(User user) {
user.setPassword(passwordEncoder.encode(user.getPassword()));
return userRepository.save(user);
}
public User findByUsername(String username) {
return userRepository.findByUsername(username);
}
}
6. 创建控制器
在`controller/LoginController.java`文件中创建登录控制器:
java
package com.example.controller;
import com.example.model.User;
import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class LoginController {
@Autowired
private UserService userService;
@GetMapping("/login")
public String login() {
return "login";
}
@PostMapping("/login")
public String login(String username, String password, Model model) {
User user = userService.findByUsername(username);
if (user != null && passwordEncoder.matches(password, user.getPassword())) {
Authentication authentication = new org.springframework.security.authentication.UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
return "redirect:/";
} else {
model.addAttribute("error", "Invalid username or password");
return "login";
}
}
}
7. 创建安全配置
在`security/WebSecurityConfig.java`文件中创建Spring Security配置类:
java
package com.example.security;
import com.example.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserService userService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
8. 创建视图
在`webapp/WEB-INF/views/login.jsp`文件中创建登录页面:
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Login</title>
</head>
<body>
<form action="login" method="post">
<div>
<label for="username">Username:</label>
<input type="text" id="username" name="username" required>
</div>
<div>
<label for="password">Password:</label>
<input type="password" id="password" name="password" required>
</div>
<div>
<input type="submit" value="Login">
</div>
</form>
<c:if test="${not empty error}">
<div style="color: red">${error}</div>
</c:if>
</body>
</html>
在`webapp/WEB-INF/views/index.jsp`文件中创建首页:
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>Welcome to the Home Page!</h1>
<div>
<a href="/logout">Logout</a>
</div>
</body>
</html>
9. 运行项目
启动Tomcat服务器,并访问`http://localhost:8080/`。在登录页面输入用户名和密码,成功登录后,将跳转到首页。
总结
本文通过JSP和Spring Security框架,实现了一个简单的登录认证示例。读者可以根据实际需求,对示例进行扩展和优化。在实际项目中,还需要考虑更多的安全因素,如密码加密、跨站请求伪造(CSRF)等。希望本文对读者有所帮助。
Comments NOTHING