SpringBoot浅析安全管理之基于数据库认证
在SpringBoot中,我们可以使用Spring Security来实现安全管理。本文将以基于数据库认证的方式为例,讲解SpringBoot安全管理的实现过程。
基础知识
在使用Spring Security进行安全管理之前,我们需要掌握以下一些基础知识:
- Spring Security的基本概念(如认证、授权等)
- 数据库的基本操作(如连接、CRUD操作等)
- 使用SpringBoot构建web应用的基础知识
实现步骤
下面将详细讲解基于数据库认证的SpringBoot安全管理实现步骤。
步骤1:添加依赖
在SpringBoot中使用Spring Security需要添加相应的依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
步骤2:配置安全认证信息
在配置文件(如application.yml)中配置安全认证信息:
spring:
security:
user:
name: admin
password: 123456
roles: admin
上面的配置中,我们添加了一个用户admin,密码为123456,角色为admin。
步骤3:配置数据库连接信息
在配置文件中配置数据库连接信息:
spring:
datasource:
url: jdbc:mysql://localhost:3306/test
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
步骤4:创建用户表和角色表
在MySQL数据库中创建用户表和角色表:
CREATE TABLE `users` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`username` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`enabled` tinyint(1) NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `authorities` (
`username` varchar(255) NOT NULL,
`authority` varchar(255) NOT NULL,
PRIMARY KEY (`username`,`authority`)
);
步骤5:添加用户和角色数据
在users表中添加用户数据:
INSERT INTO `users` (`id`, `username`, `password`, `enabled`) VALUES (1, 'admin', '$2a$10$AGYht5DPHB2gwZzvxHsEkOa7gwjleC2.nVGLPleqV88wHHo/1b8fa', 1);
密码经过加密处理,我们可以使用在线工具进行生成。
在authorities表中添加用户角色数据:
INSERT INTO `authorities` (`username`, `authority`) VALUES ('admin', 'admin');
步骤6:实现认证
创建一个实现UserDetailsService接口的类(如UserDetailsServiceImpl类):
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("用户名不存在!");
}
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(),
AuthorityUtils.commaSeparatedStringToAuthorityList(user.getAuthorities()));
}
}
在上面的代码中,我们使用userRepository查询用户信息。如果用户不存在,我们将抛出UsernameNotFoundException异常。
步骤7:实现授权
创建一个实现WebSecurityConfigurerAdapter的类(如SecurityConfig类):
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("admin")
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").defaultSuccessUrl("/index")
.and()
.logout().logoutUrl("/logout").logoutSuccessUrl("/login").invalidateHttpSession(true).deleteCookies("JSESSIONID")
.and()
.httpBasic().disable();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
在上面的代码中,我们实现了对/admin/**资源的访问需要具有admin角色的用户才能访问,其他资源需要进行认证才能访问。
同时,我们还通过formLogin()方法指定了登录页面,登录成功后跳转的页面等。
示例1:使用@PreAuthorize注解做方法级别的授权
在某个Controller类(如AdminController类)中的方法上使用@PreAuthorize注解,实现方法级别的授权:
@Controller
@RequestMapping("/admin")
public class AdminController {
@PreAuthorize("hasRole('ROLE_ADMIN')")
@RequestMapping("/userlist")
public String userList(Model model) {
List<User> userList = new ArrayList<>();
// 获取用户列表数据
model.addAttribute("userList", userList);
return "userList";
}
}
在上面的代码中,我们只允许具有admin角色的用户访问/userlist方法。
示例2:使用thymeleaf的sec标签实现页面级别的授权
在页面中使用thymeleaf的sec标签,实现页面级别的授权:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<meta charset="UTF-8">
<title>用户列表</title>
</head>
<body>
<h2>用户列表</h2>
<div sec:authorize="hasRole('ROLE_ADMIN')">
<table>
<thead>
<tr>
<th>用户名</th>
<th>姓名</th>
<th>性别</th>
</tr>
</thead>
<tbody>
<tr th:each="user : ${userList}">
<td th:text="${user.username}"></td>
<td th:text="${user.name}"></td>
<td th:text="${user.sex == 1 ? '男' : '女'}"></td>
</tr>
</tbody>
</table>
</div>
<div sec:authorize="!hasRole('ROLE_ADMIN')">
没有权限访问该页面!
</div>
</body>
</html>
在上面的代码中,我们使用sec:authorize标签实现了对有admin角色的用户才显示用户列表,其他用户将看到“没有权限访问该页面!”文本。
总结
本文介绍了基于数据库认证的SpringBoot安全管理实现步骤,同时也提供了两个示例来帮助读者理解如何在具体应用中使用安全管理功能。当然,仅仅是浅析安全管理,读者可以进一步深入到Spring Security进行学习。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot浅析安全管理之基于数据库认证 - Python技术站