Spring Security 与跨域配置解析:在线招投标系统后端设计

52 阅读3分钟

背景:药品在线招投标系统 - 后端服务

作为学校课程设计,该系统虽简洁但聚焦于核心功能实现,重点将围绕 Spring Boot Security Security 的关键知识点展开解析。项目源码可参考:Gitee 仓库

项目简介

基于 Spring Boot 3.3.4 开发的药品在线招投标系统后端服务,提供标准化 RESTful API 接口,支撑前端完成招投标全流程交互。

技术栈

  • 框架:Spring Boot 3.3.4
  • Java 版本:JDK 17
  • 数据库:MySQL
  • ORM:Spring Data JPA
  • 安全框架:Spring Security + JWT
  • 构建工具:Maven

跨域配置(CorsConfig)

前后端分离架构中,跨域请求是常见场景。以下是项目中基于 Spring 的跨域解决方案:

package com.ecut.drug_bid.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")  // 对所有接口生效
                .allowedOriginPatterns("*")  // 允许所有来源(生产环境需指定具体域名)
                .allowedMethods("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS")  // 允许的HTTP方法
                .allowedHeaders("*")  // 允许所有请求头
                .allowCredentials(false)  // 不允许携带凭证(与通配符来源兼容)
                .maxAge(3600);  // 预检请求缓存时间(1小时)
    }

    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOriginPattern("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        config.setAllowCredentials(false);
        config.setMaxAge(3600L);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

跨域配置解析

  1. 为何需要跨域配置? 浏览器的同源策略规定:只有协议、域名、端口完全一致的请求才被视为 “同源”,否则会被拦截。前后端分离架构中,前端(如http://localhost:8080)与后端(如http://localhost:8081)通常不同源,因此需通过 CORS 配置告知浏览器 “允许该前端访问后端接口”。

  2. 两种跨域配置方式项目同时使用两种配置,确保规则在不同场景下生效:

    • WebMvcConfigurer 接口:通过重写addCorsMappings方法定义跨域规则,适用于常规请求。
    • CorsFilter 过滤器:优先级高于前者,会在请求进入控制器前拦截验证,尤其适合与 Spring Security 配合(确保跨域规则在安全过滤前生效)。

    两者配置内容一致,双重配置是为兼容不同 Spring 版本或复杂场景。

CSRF(跨站请求伪造)

一种网络攻击方式:攻击者诱导已登录目标网站的用户,在不知情的情况下以其身份执行非本意操作(如转账、修改信息)。

攻击原理

  1. 用户登录网站 A 后,浏览器保留其认证信息(如 Cookie);
  2. 攻击者诱导用户访问恶意网站 B,B 构造针对 A 的请求,利用用户的认证信息向 A 发送请求;
  3. 网站 A 因请求携带合法认证信息,误认为是用户操作而执行请求。

防御措施

  • 生成 CSRF Token 并验证请求令牌;
  • 检查请求的 Referer/Origin 头,确认来源可信;
  • 设置 SameSite Cookie 属性,阻止跨域请求携带 Cookie;
  • 敏感操作要求二次验证(如验证码)。

SecurityConfig 核心配置

SecurityConfig是 Spring Security 的核心配置类,用于定义应用安全策略:

  • 通过@EnableWebSecurity启用 Web 安全功能;
  • 配置SecurityFilterChain定义安全过滤器链;
  • 依赖@RequiredArgsConstructor注入JwtAuthenticationFilter(Lombok 自动生成构造函数)。

为何禁用 CSRF?

项目作为前后端分离架构,采用 JWT 认证而非传统 Session,因此可安全禁用 CSRF:

  1. JWT 存储方式:JWT 通常放在 HTTP 请求头的Authorization字段中,而非 Cookie,浏览器不会自动附加到跨站请求;
  2. CSRF 攻击依赖:传统 CSRF 依赖浏览器自动发送 Cookie 的机制,而 JWT 不依赖此特性;
  3. 无状态设计:通过sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)设置无状态会话,进一步切断 CSRF 攻击链条。

安全保障措施

  • 自定义JwtAuthenticationFilter验证令牌合法性;
  • 采用无状态会话管理,避免会话劫持风险;
  • 细化权限控制,确保 API 访问符合角色权限规则。