- Spring Security 教程
- Spring Security - 首页
- Spring Security - 简介
- Spring Security - 架构
- Spring Security - 项目模块
- Spring Security - 环境设置
- Spring Security - 表单登录
- Spring Security - 自定义表单登录
- Spring Security - 注销
- Spring Security - 记住我
- Spring Security - 重定向
- Spring Security - 标签库
- Spring Security - XML 配置
- Spring Security - 身份验证提供程序
- Spring Security - 基本身份验证
- Spring Security - 身份验证失败处理器
- Spring Security - JWT
- Spring Security - 获取用户信息
- Spring Security - Maven
- Spring Security - 默认密码编码器
- Spring Security – 密码编码
- Spring Security - 方法级别
- Spring Security 有用资源
- Spring Security - 快速指南
- Spring Security - 有用资源
- Spring Security - 讨论
Spring Security - 基本身份验证
到目前为止,我们已经看到了基于表单的登录,其中使用基于 HTML 的表单进行用户名/密码身份验证。我们可以创建我们自己的自定义登录表单,也可以使用 Spring Security 提供的默认登录表单。还有一种方法可以请求用户名/密码,我们可以要求用户在 URL 本身使用基本身份验证传递用户名/密码。
在 Web 浏览的情况下,每当用户请求受保护的资源时,Spring Security 都会检查请求的身份验证。如果请求未经身份验证/授权,则系统将使用如下所示的默认对话框向用户询问用户名/密码
Spring Security 提供以下配置来实现基本身份验证:
protected void configure(HttpSecurity http) throws Exception {
http
// ...
.authorizeHttpRequests(request -> request.anyRequest().authenticated())
.httpBasic(Customizer.withDefaults())
.build();
}
在这里,我们正在配置 Spring Security,要求使用基本身份验证机制对每个请求进行身份验证。
让我们开始使用 Spring Security 进行实际编程。在开始使用 Spring 框架编写第一个示例之前,您必须确保已正确设置 Spring 环境,如Spring Security - 环境设置章节中所述。我们还假设您对 Spring Tool Suite IDE 有些了解。
现在让我们继续编写一个基于 Spring MVC 的应用程序,该应用程序由 Maven 管理,它将要求用户登录、验证用户,然后使用 Spring Security 表单登录功能提供注销选项。
使用 Spring Initializr 创建项目
Spring Initializr 是开始使用 Spring Boot 项目的好方法。它提供了一个易于使用的用户界面来创建项目、添加依赖项、选择 Java 运行时等。它生成一个骨架项目结构,下载后可以导入到 Spring Tool Suite 中,然后我们可以继续使用我们的现成项目结构。
我们选择一个 Maven 项目,将项目命名为 formlogin,Java 版本为 21。添加以下依赖项:
Spring Web
Spring Security
Spring Boot DevTools
Thymeleaf 是一个用于 Java 的模板引擎。它允许我们快速开发静态或动态网页以在浏览器中呈现。它具有极高的扩展性,允许我们详细定义和自定义模板的处理过程。此外,我们可以点击此链接了解更多关于 Thymeleaf 的信息。
让我们继续生成项目并下载它。然后,我们将它解压缩到我们选择的文件夹中,并使用任何 IDE 打开它。我将使用Spring Tools Suite 4。它可以从https://springframework.org.cn/tools网站免费下载,并针对 Spring 应用程序进行了优化。
包含所有相关依赖项的 pom.xml
让我们看看我们的 pom.xml 文件。它应该类似于这样:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.tutorialspoint.security</groupId>
<artifactId>formlogin</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>formlogin</name>
<description>Demo project for Spring Boot</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity6</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Spring Security 配置类
在我们的 config 包内,我们创建了 WebSecurityConfig 类。我们将使用此类进行安全配置,因此让我们使用 @Configuration 注解和 @EnableWebSecurity 对其进行注解。这样,Spring Security 就会知道将此类视为配置类。正如我们所看到的,Spring 使配置应用程序变得非常容易。
WebSecurityConfig
package com.tutorialspoint.security.formlogin.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
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.configurers.AbstractHttpConfigurer;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
protected UserDetailsService userDetailsService() {
UserDetails user = User.builder()
.username("user")
.password(passwordEncoder().encode("user123"))
.roles("USER")
.build();
UserDetails admin = User.builder()
.username("admin")
.password(passwordEncoder().encode("admin123"))
.roles("USER", "ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
}
@Bean
protected PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(request -> request.anyRequest().authenticated())
.httpBasic(Customizer.withDefaults())
.build();
}
}
配置类详细信息
让我们看看我们的配置类。
首先,我们将使用 userDetailsService() 方法创建一个 UserDetailsService 类的 bean。我们将使用此 bean 来管理此应用程序的用户。在这里,为了简单起见,我们将使用 InMemoryUserDetailsManager 实例来创建用户。这些用户以及我们给定的用户名和密码分别映射到 User 和 Admin 角色。
密码编码器
现在,让我们看看我们的 PasswordEncoder。我们将在这个例子中使用 BCryptPasswordEncoder 实例。因此,在创建用户时,我们使用 passwordEncoder 来编码我们的纯文本密码,如下所示:
.password(passwordEncoder().encode("user123"))
Http 安全配置
完成上述步骤后,我们继续进行下一个配置。在这里,我们定义了 filterChain 方法。此方法将 HttpSecurity 作为参数。我们将将其配置为使用我们的表单登录和注销功能。
我们可以观察到所有这些功能都可以在 Spring Security 中使用。让我们详细研究以下部分:
http .csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests(request -> request.anyRequest().authenticated()) .httpBasic(Customizer.withDefaults()) .build();
这里需要注意几点:
然后,我们添加需要对所有请求进行身份验证的配置。
之后,我们使用 Spring Security 的 httpBasic() 功能,如上所述。这使得浏览器请求用户名/密码。对于 REST API,我们可以将身份验证设置为 Basic Auth,我们将在本节后面看到。
控制器类
在这个类中,为了简单起见,我们为单个“/”端点创建了应用程序索引页面的映射。这将重定向到 index.html。
AuthController
package com.tutorialspoint.security.formlogin.controllers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class AuthController {
@GetMapping("/")
public String home() {
return "index";
}
}
视图
在/src/main/resources/templates文件夹中创建 index.html,内容如下,作为主页。
index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="https://www.thymeleaf.org"
xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity6">
<head>
<title>
Hello World!
</title>
</head>
<body>
<h1 th:inline="text">Hello World!</h1>
<a href="/logout" alt="logout">Sign Out</a>
</body>
<html>
运行应用程序
由于我们已经准备好所有组件,让我们运行应用程序。右键单击项目,选择以...方式运行,然后选择Spring Boot 应用程序。
它将启动应用程序,一旦应用程序启动,我们就可以运行 localhost:8080 来检查更改。
输出
现在打开 localhost:8080,您可以看到浏览器通过系统对话框请求用户名/密码。
浏览器的用户名/密码对话框
输入无效凭据
如果我们输入无效凭据,则相同的对话框将再次弹出。
用户的首页
如果我们输入用户的有效凭据,它将加载用户的首页
使用 Postman
我们可以使用 Postman 将身份验证设置为 Basic Auth,设置用户名/密码,然后发出如下所示的请求
请浏览Postman 教程以设置和学习 Postman。