1. Spring Security 介绍
1.1 什么是 Spring Security?

Spring Security 是 Spring 框架的 安全管理 模块,主要用于身份认证(Authentication)授权(Authorization),并提供多种安全防护,如:

  • 身份认证:登录验证,如用户名/密码、OAuth2、JWT、LDAP 认证等。
  • 授权控制:基于 URL、方法、注解等方式控制用户权限。
  • CSRF 防护:防止跨站请求伪造攻击。
  • 会话管理:防止会话固定攻击(Session Fixation)、并发会话控制等。
  • 密码加密:支持 BCrypt、PBKDF2、Argon2 等安全加密算法。
  • CORS 处理:跨域资源共享配置。
2. Spring Security 体系架构

Spring Security 主要由 过滤器链(SecurityFilterChain) 组成,每个请求都会经过这些过滤器来执行安全检查:

代码语言:javascript

AI代码解释

请求 -> SecurityFilterChain -> 认证 -> 授权 -> 访问控制 -> 处理请求

其中 核心组件

  • AuthenticationManager:身份认证管理器
  • UserDetailsService:用户详情管理,获取用户信息
  • PasswordEncoder:密码加密解密
  • SecurityContext:存储当前用户的安全信息
  • SecurityFilterChain:Spring Security 过滤器链
  • AuthenticationProvider:认证提供者,校验用户身份

3. Spring Security 实战
3.1 添加依赖

pom.xml 中引入 Spring Security:

代码语言:javascript

AI代码解释

<dependencies>
    <!-- Spring Security -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    
    <!-- Spring Boot Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Spring Boot Data JPA(用于数据库存储用户) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <!-- H2 Database(内存数据库) -->
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

3.2 Spring Security 默认行为

Spring Security 默认开启

  1. 登录拦截:访问所有 URL 时,默认跳转到 Spring Security 提供的 /login 页面。
  2. 默认用户:Spring Security 自动创建 用户名:user,并在启动时在控制台输出随机密码: pgsql 复制编辑 Using generated security password: e3f7e4b9-4d15-4f34-a8b9-9c845bc3c1dc
  3. 登出功能:访问 /logout 即可退出。

如何自定义 Spring Security 逻辑? 需要进行 配置


3.3 自定义用户认证
1. 创建用户实体类

代码语言:javascript

AI代码解释

package com.example.security.entity;

import jakarta.persistence.*;
import lombok.Data;

@Entity
@Table(name = "users")
@Data
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String username;
    private String password;
    private String role;  // 角色(如 ROLE_USER、ROLE_ADMIN)
}

2. 创建 UserRepository

代码语言:javascript

AI代码解释

package com.example.security.repository;

import com.example.security.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;

public interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findByUsername(String username);
}
3. 实现 UserDetailsService

Spring Security 需要获取用户信息,使用 UserDetailsService 进行查询:

代码语言:javascript

AI代码解释

package com.example.security.service;

import com.example.security.entity.User;
import com.example.security.repository.UserRepository;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

@Service
public class UserService implements UserDetailsService {
    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("用户未找到"));

        return org.springframework.security.core.userdetails.User
                .withUsername(user.getUsername())
                .password(user.getPassword())
                .roles(user.getRole()) // 角色
                .build();
    }
}

3.4 Spring Security 配置
1. 配置 SecurityFilterChain

代码语言:javascript

AI代码解释

package com.example.security.config;

import com.example.security.service.UserService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    private final UserService userService;

    public SecurityConfig(UserService userService) {
        this.userService = userService;
    }

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

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/admin/**").hasRole("ADMIN")
                .requestMatchers("/user/**").hasRole("USER")
                .anyRequest().authenticated()
            )
            .formLogin()
            .and()
            .logout();
        return http.build();
    }
}

4. Spring Security 高级功能
4.1 JWT 认证

为了让 Spring Security 支持无状态认证,我们可以使用 JWT(JSON Web Token

代码语言:javascript

AI代码解释

package com.example.security.util;

import io.jsonwebtoken.*;
import org.springframework.stereotype.Component;
import java.util.Date;

@Component
public class JwtUtil {
    private final String secretKey = "mySecretKey";  
    private final long expiration = 1000 * 60 * 60;

    public String generateToken(String username) {
        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + expiration))
                .signWith(SignatureAlgorithm.HS256, secretKey)
                .compact();
    }

    public String extractUsername(String token) {
        return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getSubject();
    }
}

5. 总结
  • Spring Security 通过 SecurityFilterChain 进行请求拦截。
  • 自定义 UserDetailsService 实现用户管理。
  • 使用 BCrypt 加密存储密码
  • JWT 认证 让系统支持 Token 方式登录。
  • CSRF 保护,避免跨站请求攻击。
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐