第2章 Spring Security 的环境设置与基础配置(2024 最新版)(下)

简介: 第2章 Spring Security 的环境设置与基础配置(2024 最新版)(下)

第2章 Spring Security 的环境设置与基础配置(2024 最新版)(上)https://developer.aliyun.com/article/1487141

2.2.3 拓展案例 1:数据库用户存储

在这个案例中,我们将展示如何在 Spring Boot 应用中使用数据库进行用户认证,这是实际生产环境中非常常见的场景。

案例 Demo

我们将创建一个简单的 Spring Boot 应用,其中用户信息存储在数据库中,并用于认证。

步骤 1:添加依赖

  1. pom.xml 文件中添加 spring-boot-starter-data-jpa 和数据库依赖(这里我们使用 H2 数据库作为示例)。
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>

步骤 2:配置数据源

  1. application.properties 文件中配置 H2 数据库。
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true

步骤 3:创建用户实体和仓库

  1. 创建用户实体 User
package com.example.demo;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class User {
    @Id
    private String username;
    private String password;
    private String role;
    // Getters and Setters
}
  1. 创建用户仓库接口 UserRepository
package com.example.demo;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, String> {
}

步骤 4:实现 UserDetailsService

  1. 创建服务 CustomUserDetailsService 实现 UserDetailsService
package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
@Service
public class CustomUserDetailsService implements UserDetailsService {
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Override
    public User loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findById(username)
            .orElseThrow(() -> new UsernameNotFoundException("User not found"));
        return new User(user.getUsername(), passwordEncoder.encode(user.getPassword()), 
                       Collections.singletonList(new SimpleGrantedAuthority(user.getRole())));
    }
}

步骤 5:配置 Spring Security

  1. 修改 SecurityConfig 类,使用自定义的 UserDetailsService 和密码编码器。
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Autowired
private CustomUserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService)
        .passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

步骤 6:运行和测试

  1. 启动 Spring Boot 应用。
  2. 通过 H2 Console 或其他方式添加用户数据到数据库。
  3. 尝试登录,验证用户认证是否工作正常。

通过此案例,你可以学习到如何在 Spring Boot 应用中结合数据库进行用户认证。这为你提供了一个更接近真实世界应用的安全配置方案。

2.2.4 拓展案例 2:OAuth2 集成

在这个案例中,我们将在 Spring Boot 应用中集成 OAuth2,允许用户使用第三方服务(如 Google, Facebook)进行登录,这是现代应用中常见的一种用户认证方式。

案例 Demo

我们的目标是创建一个 Spring Boot 应用,其中用户可以通过 Google 账户登录。

步骤 1:添加 OAuth2 客户端依赖

  1. pom.xml 中添加 spring-boot-starter-oauth2-client 依赖。
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

步骤 2:配置 OAuth2 客户端

  1. application.propertiesapplication.yml 文件中配置 Google OAuth2 客户端信息。
spring.security.oauth2.client.registration.google.client-id=your-google-client-id
spring.security.oauth2.client.registration.google.client-secret=your-google-client-secret
spring.security.oauth2.client.registration.google.scope=profile,email
  1. 您需要在 Google Cloud Console 中创建 OAuth2.0 客户端 ID,以获取客户端 ID 和秘密。

步骤 3:安全配置

  1. 修改 SecurityConfig 类,以支持 OAuth2 登录。
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .anyRequest().authenticated()
            .and()
        .oauth2Login();
}

步骤 4:创建控制器来处理登录后的操作

  1. 创建一个控制器来展示用户信息。
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
    @GetMapping("/user")
    public String user(@AuthenticationPrincipal OAuth2User principal) {
        return "Welcome, " + principal.getAttribute("name");
    }
}

步骤 5:运行和测试

  1. 启动 Spring Boot 应用。
  2. 访问 http://localhost:8080/user
  3. 应用将重定向到 Google 的登录页面。使用 Google 账户登录。
  4. 登录成功后,应显示欢迎消息和用户信息。

通过这个案例,您可以了解到如何在 Spring Boot 应用中实现 OAuth2 集成,使用户可以通过第三方服务进行身份验证,从而提供更加流畅和安全的用户体验。这种认证方式广泛应用于现代网页和移动应用中。

2.3 测试你的配置

在集成了 Spring Security 后,测试你的配置是确保一切按预期工作的重要步骤。这不仅关乎安全性,也关乎功能的正确实现。

2.3.1 基础知识详解

在集成了 Spring Security 后,测试你的配置是确保一切按预期工作的重要步骤。这部分不仅关乎安全性,也涉及到功能性的正确实现。

重要的测试概念

  1. 安全性测试:
  • 确认认证(Authentication)和授权(Authorization)机制按预期工作。
  • 验证不同用户角色的访问权限是否正确实现。
  1. 端点测试:
  • 测试不同的 API 端点以确保安全配置正确,例如,某些端点应仅对认证用户开放。
  1. 测试类型:
  • 单元测试: 测试单个方法或类的功能。
  • 集成测试: 测试多个组件协同工作的情况。
  • 端到端测试: 测试整个应用程序的工作流程。
  1. 测试工具:
  • JUnit: Java 程序员最常用的单元测试框架。
  • MockMvc: 用于模拟 MVC 测试,可以模拟发送 HTTP 请求并验证结果。
  • Spring Security Test: 提供了一系列用于测试 Spring Security 配置的工具。

如何进行有效的安全性测试

  1. 模拟认证用户: 使用测试工具模拟不同角色的用户,以测试他们的访问权限。
  2. 测试受保护的资源: 验证受保护的资源(如 API 端点)是否仅对具有适当权限的用户开放。
  3. 测试登录流程: 确保登录流程按预期工作,包括错误处理。
  4. CSRF 防护测试: 如果应用启用了 CSRF 防护,应进行相应的测试以确保其有效性。

通过这些测试,你可以保证你的 Spring Security 配置既安全又高效,为用户提供了必要的保护,同时不会干扰应用程序的正常功能。测试是任何安全配置不可或缺的一部分,它确保了安全措施的有效性和应用的健壮性。

2.3.2 主要案例:测试基本的安全配置

在这个案例中,我们将通过一个实际的示例来测试在 Spring Boot 应用中集成的基本 Spring Security 配置。

案例 Demo

假设我们的 Spring Boot 应用有两个主要端点:一个公开的主页 (/) 和一个受保护的用户页面 (/user)。我们将编写测试来验证安全配置是否按预期工作。

步骤 1:添加测试依赖

  1. pom.xml 文件中添加以下依赖,以支持测试:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

步骤 2:编写测试类

  1. 创建一个测试类 WebSecurityConfigTest
package com.example.demo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
@AutoConfigureMockMvc
public class WebSecurityConfigTest {
    @Autowired
    private MockMvc mockMvc;
    @Test
    public void accessPublic() throws Exception {
        mockMvc.perform(get("/"))
                .andExpect(status().isOk());
    }
    @Test
    public void accessPrivateUnauthenticated() throws Exception {
        mockMvc.perform(get("/user"))
                .andExpect(status().isUnauthorized());
    }
}
  1. 在这里,我们使用 MockMvc 来模拟发送 HTTP 请求到不同的端点,并验证响应的状态码。我们期望公开页面返回 200 OK 状态,而未经认证的访问受保护的 /user 端点应返回 401 Unauthorized 状态。

步骤 3:运行测试

  1. 在 IDE 中运行测试类或使用 Maven/Gradle 命令行工具来执行测试。
  2. 检查测试结果,确认安全配置是否按预期工作。

通过这个案例,你可以验证你的 Spring Security 配置是否正确实现了基本的认证和授权。这种测试是确保应用安全性的重要步骤,能帮助你捕获潜在的安全问题和配置错误。

2.3.3 ### 拓展案例 1:测试数据库用户存储

在这个案例中,我们将测试 Spring Boot 应用中使用数据库进行用户认证的配置。假设我们的应用使用数据库来存储用户信息,并基于这些信息进行认证。

案例 Demo

假设我们已经有一个集成了数据库用户存储的 Spring Boot 应用,现在我们需要编写测试来验证用户认证功能。

步骤 1:配置测试数据库

  1. src/test/resources 目录下创建一个 application.properties 文件,配置用于测试的数据库信息(使用 H2 数据库作为示例)。
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true

步骤 2:添加测试依赖

  1. 确保在 pom.xml 中已经添加了 spring-boot-starter-testh2 数据库的依赖。
<!-- Test dependencies -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>test</scope>
</dependency>

步骤 3:编写测试类

  1. 创建一个测试类 UserAuthenticationTest
package com.example.demo;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
@AutoConfigureMockMvc
public class UserAuthenticationTest {
    @Autowired
    private MockMvc mockMvc;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @BeforeEach
    public void setup() {
        User user = new User();
        user.setUsername("testuser");
        user.setPassword(passwordEncoder.encode("password"));
        user.setRole("USER");
        userRepository.save(user);
    }
    @Test
    public void authenticateWithValidUser() throws Exception {
        mockMvc.perform(post("/login")
                .param("username", "testuser")
                .param("password", "password"))
                .andExpect(status().isOk());
    }
    @Test
    public void authenticateWithInvalidUser() throws Exception {
        mockMvc.perform(post("/login")
                .param("username", "invaliduser")
                .param("password", "password"))
                .andExpect(status().isUnauthorized());
    }
}
  1. 在这里,我们使用 MockMvc 来模拟登录请求,并验证不同用户(有效和无效)的认证结果。

步骤 4:运行测试

  1. 在 IDE 中运行测试类或使用 Maven/Gradle 命令行工具来执行测试。
  2. 检查测试结果,确认数据库用户存储和认证是否按预期工作。

通过这个案例,你可以确保你的 Spring Boot 应用中的用户认证机制(基于数据库存储)按预期运行,从而提高应用的安全性和可靠性。

2.3.4 拓展案例 2:测试 OAuth2 集成

在这个案例中,我们将演示如何测试 Spring Boot 应用中的 OAuth2 集成,确保第三方登录(如 Google OAuth2)按预期工作。

案例 Demo

假设我们的 Spring Boot 应用已经集成了 Google OAuth2 登录。我们需要编写测试来验证 OAuth2 流程。

步骤 1:添加测试依赖

  1. 确保在 pom.xml 中添加了 spring-boot-starter-test 依赖。
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

步骤 2:配置 OAuth2 测试

  1. 在测试配置中(src/test/resources/application.properties),添加用于测试的 OAuth2 配置。
spring.security.oauth2.client.registration.google.client-id=test-client-id
spring.security.oauth2.client.registration.google.client-secret=test-client-secret

步骤 3:编写测试类

  1. 创建一个测试类 OAuth2LoginTest
package com.example.demo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrlPattern;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
@AutoConfigureMockMvc
public class OAuth2LoginTest {
    @Autowired
    private MockMvc mockMvc;
    @Test
    @WithMockUser
    public void requestProtectedUrlWithUser() throws Exception {
        mockMvc.perform(get("/user"))
                .andExpect(status().isOk());
    }
    @Test
    public void requestProtectedUrlWithoutUser() throws Exception {
        mockMvc.perform(get("/user"))
                .andExpect(status().is3xxRedirection())
                .andExpect(redirectedUrlPattern("**/oauth2/authorization/google"));
    }
}
  1. 这里我们使用 WithMockUser 来模拟一个已认证的用户,以测试受保护的 URL 访问。同时,我们测试未认证用户访问受保护 URL 时的重定向行为。

步骤 4:运行测试

  1. 在 IDE 中运行测试类或使用 Maven/Gradle 命令行工具来执行测试。
  2. 检查测试结果,确认 OAuth2 集成是否按预期工作。

通过这个案例,你可以确保你的应用中的 OAuth2 集成正确实现了第三方登录流程,提供了有效的用户认证机制。这对于提供一个安全、便捷的用户登录体验至关重要。

目录
相关文章
|
21天前
|
JSON 安全 Java
什么是JWT?如何使用Spring Boot Security实现它?
什么是JWT?如何使用Spring Boot Security实现它?
76 5
|
1月前
|
Java 开发者 微服务
手写模拟Spring Boot自动配置功能
【11月更文挑战第19天】随着微服务架构的兴起,Spring Boot作为一种快速开发框架,因其简化了Spring应用的初始搭建和开发过程,受到了广大开发者的青睐。自动配置作为Spring Boot的核心特性之一,大大减少了手动配置的工作量,提高了开发效率。
52 0
|
2月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
58 4
|
2月前
|
Java API 数据库
Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐
本文通过在线图书管理系统案例,详细介绍如何使用Spring Boot构建RESTful API。从项目基础环境搭建、实体类与数据访问层定义,到业务逻辑实现和控制器编写,逐步展示了Spring Boot的简洁配置和强大功能。最后,通过Postman测试API,并介绍了如何添加安全性和异常处理,确保API的稳定性和安全性。
45 0
|
5天前
|
NoSQL Java Redis
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
44 14
|
3天前
|
XML Java 数据格式
Spring容器Bean之XML配置方式
通过对以上内容的掌握,开发人员可以灵活地使用Spring的XML配置方式来管理应用程序的Bean,提高代码的模块化和可维护性。
19 6
|
4天前
|
XML Java 数据格式
🌱 深入Spring的心脏:Bean配置的艺术与实践 🌟
本文深入探讨了Spring框架中Bean配置的奥秘,从基本概念到XML配置文件的使用,再到静态工厂方式实例化Bean的详细步骤,通过实际代码示例帮助读者更好地理解和应用Spring的Bean配置。希望对你的Spring开发之旅有所助益。
32 3
|
2月前
|
Java API Spring
在 Spring 配置文件中配置 Filter 的步骤
【10月更文挑战第21天】在 Spring 配置文件中配置 Filter 是实现请求过滤的重要手段。通过合理的配置,可以灵活地对请求进行处理,满足各种应用需求。还可以根据具体的项目要求和实际情况,进一步深入研究和优化 Filter 的配置,以提高应用的性能和安全性。
|
1月前
|
存储 运维 安全
Spring运维之boot项目多环境(yaml 多文件 proerties)及分组管理与开发控制
通过以上措施,可以保证Spring Boot项目的配置管理在专业水准上,并且易于维护和管理,符合搜索引擎收录标准。
42 2
|
1月前
|
Java Spring
[Spring]aop的配置与使用
本文介绍了AOP(面向切面编程)的基本概念和核心思想。AOP是Spring框架的核心功能之一,通过动态代理在不修改原代码的情况下注入新功能。文章详细解释了连接点、切入点、通知、切面等关键概念,并列举了前置通知、后置通知、最终通知、异常通知和环绕通知五种通知类型。
37 1
下一篇
DataWorks