Spring Boot Spring Security JDBC 身份验证

x33g5p2x  于2021-10-16 转载在 Spring  
字(7.9k)|赞(0)|评价(0)|浏览(644)

本页面将通过 Spring Boot 和 MySQL 数据库完成 Spring Security JDBC 身份验证。 Spring Security 提供了许多使用现有数据源配置执行 JDBC 身份验证的功能。在基于 JDBC 的身份验证中,用户的身份验证和授权信息存储在数据库中。

由于您已经阅读了我们之前关于基于角色的授权的文章,您可能对 Spring Security 有了基本的了解。

###我们将构建什么

在此示例中,我们将创建具有不同角色的用户,并根据存储在 MySQL 数据库中的登录用户信息对每个请求进行身份验证和授权。为此,我们需要执行以下操作:

1. 捕获用户信息并以散列形式存储密码

@Bean
public BCryptPasswordEncoder passwordEncoder() {
	return new BCryptPasswordEncoder();
}

2. 通过覆盖类 WebSecurityConfigurerAdapterconfigure(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();
}

简而言之:

  1. /register-user 用于创建一个新用户,每个人都可以访问。
  2. /admin 只能被具有角色 ‘ADMIN’ 的用户访问。
  3. /user 允许角色为 'ADMIN''USER' 的用户。
  4. / (root) 允许所有人使用。

使用的技术

查找此应用程序中使用的所有技术的列表。

  1. Spring Tool Suite 4
  2. JDK 8
  3. Spring Boot 2.1.8.RELEASE
  4. Spring Security 5.1.6.RELEASE
  5. MySQL Database
  6. Maven 3

需要依赖

要解决 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 文件中配置数据库连接字符串,以建立应用程序和数据库之间的连接。
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 端点,如下所示:

  1. /register-user 用于创建一个新用户,每个人都可以访问。
  2. /admin 只能被具有角色 ‘ADMIN’ 的用户访问。
  3. /user 允许角色为 'ADMIN''USER' 的用户。
  4. / (root) 允许所有人使用。

用户控制器.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 页面:

  1. 打开邮递员。
  2. 使用 HTTP 方法 POST 访问 localhost:8080/register-user 将自己注册为 ROLE_ADMINROLE_USER。下面提供了 JSON:
#JSON for ADMIN role
{
	"userName":"superman",
	"password":"super",
	"roles":"ROLE_ADMIN"
}
#JSON for USER role
{
	"userName":"ironman",
	"password":"iron",
	"roles":"ROLE_USER"
}
  1. 成功创建用户后,您将可以留言 User created 🙂

对于 /admin 页面:

  1. 点击 localhost:8080/admin,它会将您重定向到登录页面。
  2. 以具有“ADMIN”角色的用户登录,验证成功后,将显示管理页面。
  3. 同样,尝试使用没有“ADMIN”角色的用户访问管理 URL(用户具有角色“USER”),Spring Security 将阻止您访问 /admin 页面。

对于/用户页面:

  1. 点击 localhost:8080/user,它会将您重定向到登录页面。
  2. 以“USER”用户身份登录,认证成功后显示用户页面。
  3. 用户拥有角色“ADMIN”也可以访问。

对于/(根)页面:

  1. Spring Security 允许所有人访问 localhost:8080/ URL。它不需要进行身份验证。
    `` 下载源代码:spring-security-jdbc-authentication-with-spring-boot.zip

相关文章

微信公众号

最新文章

更多