1072 字
约 3 分钟
1
SpringBoot 安全
2026-09-19
无标签

第19章 SpringBoot 安全

掌握SpringBoot Security安全框架和最佳实践 💻 查看完整代码 - 在线IDE体验

🎯 学习目标

  • 安全基础:了解Web应用安全原理
  • Spring Security:掌握安全框架配置
  • 认证授权:实现用户认证和权限控制
  • JWT集成:无状态Token认证
  • OAuth2:第三方登录集成
  • 安全防护:防范常见安全攻击

🔧 核心概念

  • Authentication:身份认证
  • Authorization:权限授权
  • Principal:用户主体
  • Authorities:用户权限
  • SecurityContext:安全上下文
  • Filter Chain:安全过滤器链

📦 依赖配置

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

<!-- Web支持 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- JWT支持 -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.5</version>
</dependency>

<!-- 数据库支持 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

🔄 安全架构流程

请求到达→安全过滤器→身份认证→权限检查→访问控制→业务处理

🛡️ 安全层次架构

多层安全防护体系

                    🔐 认证层 - Authentication Layer
                
                    🔑 授权层 - Authorization Layer
                
                    🔒 加密层 - Encryption Layer
                
                    ✅ 验证层 - Validation Layer

⚙️ 基础安全配置

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig {

    @Autowired
    private UserDetailsService userDetailsService;

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

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(authz -> authz
                .requestMatchers("/api/public/**").permitAll()
                .requestMatchers("/api/admin/**").hasRole("ADMIN")
                .requestMatchers("/api/user/**").hasAnyRole("USER", "ADMIN")
                .anyRequest().authenticated()
            )
            .formLogin(form -> form
                .loginPage("/login")
                .defaultSuccessUrl("/dashboard")
                .permitAll()
            )
            .logout(logout -> logout
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login?logout")
                .permitAll()
            )
            .sessionManagement(session -> session
                .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                .maximumSessions(1)
                .maxSessionsPreventsLogin(false)
            )
            .csrf(csrf -> csrf.disable())
            .headers(headers -> headers.frameOptions().deny());

        return http.build();
    }
}

👤 用户认证服务

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) 
            throws UsernameNotFoundException {
        
        User user = userRepository.findByUsername(username)
            .orElseThrow(() -> new UsernameNotFoundException(
                "用户不存在: " + username));

        return org.springframework.security.core.userdetails.User.builder()
            .username(user.getUsername())
            .password(user.getPassword())
            .authorities(getAuthorities(user.getRoles()))
            .accountExpired(false)
            .accountLocked(false)
            .credentialsExpired(false)
            .disabled(false)
            .build();
    }

    private Collection<? extends GrantedAuthority> getAuthorities(Set<Role> roles) {
        return roles.stream()
            .map(role -> new SimpleGrantedAuthority("ROLE_" + role.getName()))
            .collect(Collectors.toList());
    }
}

🔑 JWT Token配置

@Component
public class JwtTokenProvider {

    private String jwtSecret = "mySecretKey";
    private int jwtExpirationInMs = 604800000; // 7天

    public String generateToken(Authentication authentication) {
        UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();
        Date expiryDate = new Date(System.currentTimeMillis() + jwtExpirationInMs);

        return Jwts.builder()
                .setSubject(Long.toString(userPrincipal.getId()))
                .setIssuedAt(new Date())
                .setExpiration(expiryDate)
                .signWith(SignatureAlgorithm.HS512, jwtSecret)
                .compact();
    }

    public Long getUserIdFromJWT(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(jwtSecret)
                .parseClaimsJws(token)
                .getBody();

        return Long.parseLong(claims.getSubject());
    }

    public boolean validateToken(String authToken) {
        try {
            Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
            return true;
        } catch (JwtException | IllegalArgumentException e) {
            return false;
        }
    }
}

🔐 认证方式对比

Session-Cookie 认证JWT Token 认证OAuth2 第三方认证Basic 基础认证Digest 摘要认证

🛡️ 安全功能特性

CSRF 防护跨站请求伪造攻击防护XSS 防护跨站脚本攻击防护SQL 注入防护数据库注入攻击防护会话管理用户会话安全管理密码加密用户密码安全存储权限控制细粒度访问控制

🔒 方法级安全

@RestController
@RequestMapping("/api/admin")
public class AdminController {

    @PreAuthorize("hasRole('ADMIN')")
    @GetMapping("/users")
    public List<User> getAllUsers() {
        return userService.findAll();
    }

    @PreAuthorize("hasRole('ADMIN') and #id == authentication.principal.id")
    @DeleteMapping("/users/{id}")
    public void deleteUser(@PathVariable Long id) {
        userService.deleteById(id);
    }

    @PostAuthorize("returnObject.username == authentication.name")
    @GetMapping("/profile")
    public User getProfile() {
        return userService.getCurrentUser();
    }

    @Secured({"ROLE_ADMIN", "ROLE_MANAGER"})
    @GetMapping("/reports")
    public List<Report> getReports() {
        return reportService.findAll();
    }
}

🌐 OAuth2 集成

# application.yml
spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: your-google-client-id
            client-secret: your-google-client-secret
            scope: profile, email
          github:
            client-id: your-github-client-id
            client-secret: your-github-client-secret
            scope: user:email
        provider:
          google:
            authorization-uri: https://accounts.google.com/o/oauth2/auth
            token-uri: https://oauth2.googleapis.com/token
            user-info-uri: https://www.googleapis.com/oauth2/v2/userinfo
            user-name-attribute: email

@Configuration
public class OAuth2Config {
    
    @Bean
    public OAuth2UserService<OAuth2UserRequest, OAuth2User> oauth2UserService() {
        return new CustomOAuth2UserService();
    }
}

📊 安全配置对比

认证方式 优点 缺点 适用场景
Session-Cookie 简单易用,服务端控制 不适合分布式 传统Web应用
JWT Token 无状态,跨域支持 Token泄露风险 微服务架构
OAuth2 第三方授权,安全 配置复杂 开放平台
Basic Auth 简单直接 安全性较低 内部API
API Key 轻量级 功能有限 公开API

🎯 安全最佳实践

安全开发建议1. 密码策略:强制复杂密码,定期更换2. 输入验证:严格验证所有用户输入3. 权限最小化:遵循最小权限原则4. 安全传输:使用HTTPS加密传输5. 日志审计:记录安全相关操作6. 定期更新:及时更新安全补丁7. 安全测试:定期进行安全测试8. 错误处理:避免泄露敏感信息

下一章节

🎉 恭喜完成第19章学习!

你已经掌握了SpringBoot Security安全的核心技能,接下来学习事务管理! 🚀 下一章:SpringBoot Transaction 🏠 返回课程首页

SpringBoot 安全
http://www.clxhxhhr.top/posts/2887/
作者
clxstart
发布于
2026-09-19
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。