本页面将通过 Spring Boot 和 MySQL 数据库完成 Spring Security JDBC 身份验证。 Spring Security 提供了许多使用现有数据源配置执行 JDBC 身份验证的功能。在基于 JDBC 的身份验证中,用户的身份验证和授权信息存储在数据库中。
由于您已经阅读了我们之前关于基于角色的授权的文章,您可能对 Spring Security 有了基本的了解。
###我们将构建什么
在此示例中,我们将创建具有不同角色的用户,并根据存储在 MySQL 数据库中的登录用户信息对每个请求进行身份验证和授权。为此,我们需要执行以下操作:
1. 捕获用户信息并以散列形式存储密码
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
2. 通过覆盖类 WebSecurityConfigurerAdapter
的 configure(AuthenticationManagerBuilder *auth*)
方法来配置 JDBC 身份验证
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource).passwordEncoder(passwordEncoder());
}
3.JdbcUserDetailsManager
类是 JDBC 用户管理服务,用于对 Spring 模式提供的用户和组执行 CRUD 操作,它包含所有 DML(数据操作语言)和 DQL(数据查询语言)命令。
@Bean
public JdbcUserDetailsManager jdbcUserDetailsManager() {
return new JdbcUserDetailsManager(dataSource);
}
4. 通过覆盖 configure(HttpSecurity *http*)
方法根据登录的用户角色对请求进行身份验证
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers("/admin").hasRole(ADMIN)
.antMatchers("/user").hasAnyRole(ADMIN, USER)
.antMatchers("/", "/register-user").permitAll()
.and().formLogin();
}
简而言之:
查找此应用程序中使用的所有技术的列表。
要解决 JAR 依赖项,请将以下代码添加到 pom.xml。
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
我们在 STS 4 IDE 中的应用程序的最终项目结构如下所示:
MySQL数据库的以下表结构用于存储用户信息和角色。由于我们使用 JDBC,因此必须手动创建表。
-- users table structure
CREATE TABLE `users` (
`username` VARCHAR(50) NOT NULL,
`password` VARCHAR(120) NOT NULL,
`enabled` TINYINT(1) NOT NULL,
PRIMARY KEY (`username`)
);
-- authorities table structure
CREATE TABLE `authorities` (
`username` VARCHAR(50) NOT NULL,
`authority` VARCHAR(50) NOT NULL,
KEY `username` (`username`),
CONSTRAINT `authorities_ibfk_1` FOREIGN KEY (`username`)
REFERENCES `users` (`username`)
);
在 application.properties 文件中配置数据库连接字符串,以建立应用程序和数据库之间的连接。
application.properties
#MySQL database connection strings
spring.datasource.url=jdbc:mysql://localhost:3306/spring_security
spring.datasource.username=root
spring.datasource.password=root
创建一个 MyUser
模型类,其中包含用户的所有属性。
MyUser.java
package org.websparrow.model;
public class MyUser {
private String userName;
private String password;
private String roles;
// Generate Getters and Setters...
}
UserController
类为应用程序用户公开 REST 端点。在这个控制器类中,我们创建了 4 个不同的 REST 端点,如下所示:
用户控制器.java
package org.websparrow.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.provisioning.JdbcUserDetailsManager;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.websparrow.model.MyUser;
@RestController
public class UserController {
@Autowired
private JdbcUserDetailsManager jdbcUserDetailsManager;
@Autowired
private BCryptPasswordEncoder passwordEncoder;
@PostMapping(value = "/register-user")
public String regiter(@RequestBody MyUser myUser) {
List<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority(myUser.getRoles()));
String encodededPassword = passwordEncoder.encode(myUser.getPassword());
User user = new User(myUser.getUserName(), encodededPassword, authorities);
jdbcUserDetailsManager.createUser(user);
return "User created :)";
}
@GetMapping(value = "/admin")
public String admin() {
return "<h3>Welcome Admin :)</h3>";
}
@GetMapping(value = "/user")
public String user() {
return "<h3>Hello User :)</h3>";
}
@GetMapping(value = "/")
public String welcome() {
return "<h3>Welcome :)</h3>";
}
}
WebSecurityConfig
是自定义的安全配置类,它覆盖了 WebSecurityConfigurerAdapter
类提供的 Spring Security 的功能。 WebSecurityConfig
类通过 JDBC 覆盖 configure(AuthenticationManagerBuilder *auth*)
方法对用户进行身份验证,并通过覆盖 configure(HttpSecurity *http*)
方法根据登录用户的 角色/权限 授权每个请求.
WebSecurityConfig.java
package org.websparrow.config;
import javax.sql.DataSource;
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.provisioning.JdbcUserDetailsManager;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private static final String ADMIN = "ADMIN";
private static final String USER = "USER";
@Autowired
private DataSource dataSource;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource)
.passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers("/admin").hasRole(ADMIN)
.antMatchers("/user").hasAnyRole(ADMIN, USER)
.antMatchers("/", "/register-user").permitAll()
.and().formLogin();
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public JdbcUserDetailsManager jdbcUserDetailsManager() {
return new JdbcUserDetailsManager(dataSource);
}
}
SpringBootApp
类包含主要方法并负责启动应用程序。
SpringBootApp.java
package org.websparrow;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackages = "org.websparrow.*")
public class SpringBootApp {
public static void main(String[] args) {
SpringApplication.run(SpringBootApp.class, args);
}
}
要测试应用程序,请通过执行上述类来启动 Spring Boot 应用程序,并按照以下步骤操作:
对于 /register-user 页面:
#JSON for ADMIN role
{
"userName":"superman",
"password":"super",
"roles":"ROLE_ADMIN"
}
#JSON for USER role
{
"userName":"ironman",
"password":"iron",
"roles":"ROLE_USER"
}
对于 /admin 页面:
对于/用户页面:
对于/(根)页面:
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://www.websparrow.org/spring/spring-security-jdbc-authentication-with-spring-boot
内容来源于网络,如有侵权,请联系作者删除!