下面是使用Spring Security实现数据库认证和密码加密/解密的完整攻略:
一、创建数据库
首先,我们需要创建一个数据库,用于存储用户信息。假设我们的数据库名为security_demo
,包含一张名为user
的用户表,其中包含id、username、password、enabled
四个字段。我们可以使用如下的SQL语句创建该表:
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(100) NOT NULL,
`enabled` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`),
UNIQUE KEY `UK_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
二、添加相关依赖
接下来,我们需要在pom.xml
文件中添加相关依赖。具体依赖如下:
<!-- Spring Security依赖 -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.3.4.RELEASE</version>
</dependency>
<!-- 数据库驱动依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
</dependency>
三、配置Spring Security
接下来,我们需要在Spring Security
的配置文件中添加相关配置,使其能够实现基于数据库的认证和密码加密/解密。假设我们的Spring Security配置文件名为SecurityConfig.java
,其内容如下:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/css/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login").permitAll()
.and()
.logout().permitAll();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.usersByUsernameQuery("select username, password, enabled from user where username = ?")
.authoritiesByUsernameQuery("select u.username, r.role_name as authority "
+ "from user u "
+ "inner join user_role ur on u.id = ur.user_id "
+ "inner join role r on ur.role_id = r.id "
+ "where u.username = ?");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
其中,
@Configuration
注解用于表示该类是一个Spring配置类;@EnableWebSecurity
注解用于表示启用Spring Security功能;SecurityConfig
类继承了WebSecurityConfigurerAdapter
类,用于重写WebSecurityConfigurerAdapter
类中定义的方法;@Autowired
注解用于自动注入DataSource
类型的数据源;configure(HttpSecurity http)
方法用于配置HttpSecurity
对象,用于设置安全相关的配置信息。上述配置中,我们禁用了csrf
攻击防御功能,允许所有用户访问/css
目录下的静态资源,其它请求需要进行认证才能访问。另外,我们配置了默认的登录界面为/login
;configureGlobal(AuthenticationManagerBuilder auth)
方法用于配置全局安全相关的信息,主要包括认证方式和密码加密方式。在上述配置中,我们使用了JdbcDaoAuthenticationProvider
实现基于数据库的认证方式,并自定义了查询用户信息和查询用户权限信息的SQL语句,其中usersByUsernameQuery
用于查询用户信息,authoritiesByUsernameQuery
用于查询用户权限信息;passwordEncoder
方法用于定义密码加密方式,我们使用了BCryptPasswordEncoder
类实现密码加密。
四、实现用户注册页面
接下来,我们需要实现用户注册页面和相关的控制器。我们可以新建一个名为UserController.java
的控制器类,其内容如下:
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/register")
public String register(Model model) {
model.addAttribute("user", new User());
return "register";
}
@PostMapping("/register")
public String saveUser(@ModelAttribute("user") User user) {
userService.save(user);
return "redirect:/login?registered";
}
}
其中,
@Controller
注解用于表示该类是一个控制器;@RequestMapping("/user")
注解用于表示该控制器路径的前缀为/user
;UserController
接受一个名为userService
的服务类;register(Model model)
方法用于返回用户注册页面的模板名称;saveUser(@ModelAttribute("user") User user)
方法用于保存用户信息,并跳转到登录页。
另外,我们还需要新建一个名为User.java
的实体类,用于表示用户信息。其内容如下:
public class User {
private Long id;
@NotEmpty
private String username;
@NotEmpty
private String password;
private boolean enabled = true;
// getters and setters
}
其中,
User
实体类包含id、username、password、enabled
四个属性,分别对应于数据库表中的四个字段。@NotEmpty
注解用于表示username
和password
字段是必填字段。
五、实现用户服务类
接下来,我们需要实现一个名为 UserService
的服务类,用于处理用户的注册和查询操作。我们可以先定义一个名为 UserRepository
的接口,其内容如下:
public interface UserRepository {
void save(User user);
User findByUsername(String username);
}
其中,
UserRepository
接口定义了两个方法,分别用于保存用户信息和查询用户信息。
接下来,我们实现一个名为 UserServiceImpl
的实现类,用于实现上述接口中定义的方法。其内容如下:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private UserRepository userRepository;
@Override
public void save(User user) {
String encodedPassword = passwordEncoder.encode(user.getPassword());
user.setPassword(encodedPassword);
userRepository.save(user);
}
@Override
public User findByUsername(String username) {
return userRepository.findByUsername(username);
}
}
其中,
@Service
注解用于表示该类是一个服务类;@Autowired
注解用于自动注入PasswordEncoder
类型的对象和UserRepository
类型的对象;save(User user)
方法用于保存用户信息,其中passwordEncoder.encode()
方法用于加密用户密码;findByUsername(String username)
方法用于根据用户名查询用户信息。
六、实现注册页面模板
最后,我们需要实现一个名为 register.html
的模板,用于渲染用户注册页面的UI界面。其内容如下:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>User Registration</title>
<link th:href="@{/css/main.css}" rel="stylesheet" type="text/css"/>
</head>
<body>
<h2>User Registration</h2>
<form th:action="@{/user/register}" th:object="${user}" method="post">
<input type="text" th:field="*{username}" placeholder="Username" required autofocus/>
<input type="password" th:field="*{password}" placeholder="Password" required/>
<button type="submit">Register</button>
</form>
</body>
</html>
其中,
- 我们使用了Thymeleaf模板引擎来实现注册页面的渲染。下面是对这些Thymeleaf标记的解释:
th:action
属性用于设置表单的提交地址;th:object
属性用于给表单绑定模型对象;th:field
属性用于给表单控件绑定模型对象中的属性;*{username}
用于给input
标记绑定User
实体类中的username
属性;*{password}
用于给input
标记绑定User
实体类中的password
属性。
至此,我们已经完整地实现了 Spring Security 使用数据库认证及用户密码加密和解密功能的完整攻略。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Security使用数据库认证及用户密码加密和解密功能 - Python技术站