Skip to content

Spring Security 安全框架

Spring Security 是 Spring 生态系统中最重要的安全框架之一,为 Java 应用程序提供了全面的安全服务。它提供了认证(Authentication)和授权(Authorization)功能,帮助开发者构建安全可靠的 Web 应用程序。

什么是 Spring Security?

Spring Security 是一个功能强大且高度可定制的身份验证和访问控制框架。它是保护基于 Spring 的应用程序的事实标准,专注于为 Java 应用程序提供身份验证和授权功能。

核心概念

IMPORTANT

Spring Security 的两个核心概念:

  • 认证(Authentication):验证用户身份,确认"你是谁"
  • 授权(Authorization):验证用户权限,确认"你能做什么"

为什么需要 Spring Security?

在现代 Web 应用中,安全是至关重要的。没有适当的安全措施,应用程序面临各种威胁:

常见安全威胁

安全威胁

  • 未授权访问:恶意用户访问敏感数据
  • 会话劫持:攻击者窃取用户会话
  • CSRF 攻击:跨站请求伪造
  • SQL 注入:通过恶意输入攻击数据库
  • XSS 攻击:跨站脚本攻击

Spring Security 解决的问题

Spring Security 通过以下方式解决这些安全问题:

  1. 统一的安全配置:集中管理所有安全相关配置
  2. 多种认证方式:支持表单登录、JWT、OAuth2 等
  3. 细粒度权限控制:方法级和 URL 级权限控制
  4. 自动防护:内置 CSRF、XSS 等攻击防护
  5. 会话管理:安全的会话创建和管理

实际业务场景

让我们通过一个电商系统的例子来理解 Spring Security 的应用:

场景描述

在一个电商平台中,不同角色的用户需要不同的权限:

  • 游客:只能浏览商品,不能下单
  • 普通用户:可以浏览商品、下单、查看订单
  • 管理员:可以管理商品、查看所有订单
  • 超级管理员:拥有系统的所有权限

Spring Security 核心组件

1. 安全过滤器链(Security Filter Chain)

Spring Security 的核心是一系列过滤器组成的过滤器链:

2. 认证管理器(Authentication Manager)

负责处理认证请求,验证用户凭据:

kotlin
@Configuration
@EnableWebSecurity
class SecurityConfig {

    @Bean
    fun authenticationManager(
        authenticationConfiguration: AuthenticationConfiguration
    ): AuthenticationManager {
        return authenticationConfiguration.authenticationManager
    }

    @Bean
    fun passwordEncoder(): PasswordEncoder {
        // 使用 BCrypt 加密算法
        return BCryptPasswordEncoder()
    }

    @Bean
    fun userDetailsService(): UserDetailsService {
        return CustomUserDetailsService()
    }
}
java
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public AuthenticationManager authenticationManager(
            AuthenticationConfiguration authenticationConfiguration) throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }

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

    @Bean
    public UserDetailsService userDetailsService() {
        return new CustomUserDetailsService();
    }
}

3. 用户详情服务(UserDetailsService)

从数据源加载用户信息:

kotlin
@Service
class CustomUserDetailsService : UserDetailsService {

    @Autowired
    private lateinit var userRepository: UserRepository

    override fun loadUserByUsername(username: String): UserDetails {
        // 从数据库查询用户信息
        val user = userRepository.findByUsername(username)
            ?: throw UsernameNotFoundException("用户不存在: $username")

        // 构建用户权限列表
        val authorities = user.roles.map {
            SimpleGrantedAuthority("ROLE_${it.name}")
        }

        // 返回 Spring Security 用户对象
        return User.builder()
            .username(user.username)
            .password(user.password) // 已加密的密码
            .authorities(authorities)
            .accountExpired(false)
            .accountLocked(false)
            .credentialsExpired(false)
            .disabled(false)
            .build()
    }
}

快速开始

1. 添加依赖

build.gradle.kts 中添加 Spring Security 依赖:

kotlin
dependencies {
    implementation("org.springframework.boot:spring-boot-starter-security")
    implementation("org.springframework.boot:spring-boot-starter-web")
    // 如果使用 Thymeleaf 模板
    implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
    implementation("org.thymeleaf.extras:thymeleaf-extras-springsecurity6")
}

2. 基础配置

kotlin
@Configuration
@EnableWebSecurity
class WebSecurityConfig {

    @Bean
    fun filterChain(http: HttpSecurity): SecurityFilterChain {
        return http
            .authorizeHttpRequests { authz ->
                authz
                    .requestMatchers("/", "/home", "/register").permitAll() // 允许所有人访问
                    .requestMatchers("/admin/**").hasRole("ADMIN") // 仅管理员访问
                    .anyRequest().authenticated() // 其他请求需要认证
            }
            .formLogin { form ->
                form
                    .loginPage("/login") // 自定义登录页面
                    .permitAll()
            }
            .logout { logout ->
                logout.permitAll()
            }
            .build()
    }
}

3. 创建用户

kotlin
@Configuration
class DataConfig {

    @Bean
    fun users(): InMemoryUserDetailsManager {
        // 创建测试用户
        val user = User.withDefaultPasswordEncoder()
            .username("user")
            .password("password")
            .roles("USER")
            .build()

        val admin = User.withDefaultPasswordEncoder()
            .username("admin")
            .password("admin123")
            .roles("USER", "ADMIN")
            .build()

        return InMemoryUserDetailsManager(user, admin)
    }
}

TIP

在生产环境中,永远不要使用 withDefaultPasswordEncoder(),应该使用专门的密码编码器如 BCryptPasswordEncoder

主要特性

🔐 认证方式

  • 表单认证:传统的用户名密码登录
  • HTTP Basic:HTTP 基本认证
  • JWT Token:无状态的令牌认证
  • OAuth2/OpenID Connect:第三方登录
  • LDAP:企业级目录服务认证

🛡️ 安全防护

  • CSRF 防护:跨站请求伪造防护
  • 会话管理:会话固定攻击防护
  • 密码编码:安全的密码存储
  • 安全头部:自动添加安全 HTTP 头部

🎯 权限控制

  • URL 级权限:基于 URL 模式的访问控制
  • 方法级权限:使用注解进行方法级权限控制
  • 表达式权限:使用 SpEL 表达式进行复杂权限判断

学习路径

NOTE

这个学习笔记将帮助您循序渐进地掌握 Spring Security,从基础概念到高级应用,每个章节都包含详细的代码示例和实际业务场景。