淘东电商项目(68) -互联网安全架构设计(黑名单拦截及MD5加签)

简介: 淘东电商项目(68) -互联网安全架构设计(黑名单拦截及MD5加签)

引言

本文代码已提交至Github(版本号:d439ec96b39dc0adf0d697cbc6bfc87c1c3b7dc8),有兴趣的同学可以下载来看看:https://github.com/ylw-github/taodong-shop

在上一篇博客《淘东电商项目(67) -互联网安全架构设计(方法论)》,主要讲解了互联网安全架构设计的方法,主要介绍了如下几种:

  1. 基于网关实现IP黑名单与名单拦截
  2. API接口实现Token授权认证
  3. 使用MD5实现API接口验证签名,防止抓包篡改数据
  4. 实现API接口安全加密传输(公钥和私钥互换机制)
  5. 基于Oauth2.0 实现API接口开放平台
  6. 接口参数使用网关实现防止XSS、SQL注入
  7. 定期工具实现代码健康扫描

本文开始讲解具体的代码实现。

本文目录结构:

l____引言

l____ 1.实现思路

l____ 2.代码实现

l________ 2.1 数据库代码

l________ 2.2 建造者模式

l________ 2.3 建造者模式使用

l____ 3.测试

1.实现思路

在上图,可以看到,外网访问时会经过我们的网关,如果我们需要对访问者做出安全措施,必须在网关上做处理,如:“ip黑名单处理”、“MD5加签处理”等。

在SpringCloud中,这些处理均在zuul网关过滤器中处理,伪代码如下:

public class GatewayFilter extends ZuulFilter {
  @Override
  public Object run() throws ZuulException {
    RequestContext ctx = RequestContext.getCurrentContext();
    HttpServletRequest request = ctx.getRequest();
    HttpServletResponse response = ctx.getResponse();
    response.setContentType("UTF-8");
    // TODO 1.验证ip地址是否在黑名单里,如果是则拒绝访问
    // TODO 2.通过MD5验签,判断参数是否被篡改
    // TODO 3.其它......
    return null;
  }

可以看到上面的代码是一步一步去处理的,其实是可以优化这种写法的,本文用到“建造者模式”。

2.代码实现

2.1 数据库代码

先贴上黑名单表的sql:

CREATE TABLE `blacklist` (
  `ID` int(11) NOT NULL COMMENT '主键id',
  `IP_ADDRES` varchar(255) DEFAULT NULL COMMENT 'ip地址',
  `RESTRICTION_TYPE` varchar(255) DEFAULT NULL COMMENT '限制类型',
  `AVAILABILITY` varchar(255) DEFAULT NULL COMMENT '是否可用',
  `REVISION` int(11) DEFAULT NULL COMMENT '乐观锁',
  `CREATED_BY` varchar(32) DEFAULT NULL COMMENT '创建人',
  `CREATED_TIME` datetime DEFAULT NULL COMMENT '创建时间',
  `UPDATED_BY` varchar(32) DEFAULT NULL COMMENT '更新人',
  `UPDATED_TIME` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2.2 建造者模式

建造者模式之前我的博客有讲解过,有兴趣的童鞋可以参阅:

2.3 建造者模式使用

①定义接口:

/**
 * description: 网关行为建造者
 * create by: YangLinWei
 * create time: 2020/5/20 9:09 上午
 */
public interface GatewayBuild {
  /**
   * 黑名单拦截
   */
  Boolean blackBlock(RequestContext ctx, String ipAddres, HttpServletResponse response);
  /**
   * 参数验证
   */
  Boolean toVerifyMap(RequestContext ctx, String ipAddres, HttpServletRequest request);
}

②接口实现:

/**
 * description: 参数验证
 * create by: YangLinWei
 * create time: 2020/5/20 9:09 上午
 */
@Slf4j
@Component
public class VerificationBuild implements GatewayBuild {
  @Autowired
  private BlacklistMapper blacklistMapper;
  @Override
  public Boolean blackBlock(RequestContext ctx, String ipAddres, HttpServletResponse response) {
    // 2.查询数据库黑名单
    Blacklist meiteBlacklist = blacklistMapper.findBlacklist(ipAddres);
    if (meiteBlacklist != null) {
      resultError(ctx, "ip:" + ipAddres + ",Insufficient access rights");
      return false;
    }
    log.info(">>>>>>ip:{},验证通过>>>>>>>", ipAddres);
    // 3.将ip地址传递到转发服务中
    response.addHeader("ipAddres", ipAddres);
    log.info(">>>>>>ip:{},验证通过>>>>>>>", ipAddres);
    return true;
  }
  @Override
  public Boolean toVerifyMap(RequestContext ctx, String ipAddres, HttpServletRequest request) {
    // 4.外网传递参数验证
    Map<String, String> verifyMap = SignUtil.toVerifyMap(request.getParameterMap(), false);
    if (!SignUtil.verify(verifyMap)) {
      resultError(ctx, "ip:" + ipAddres + ",Sign fail");
      return false;
    }
    return true;
  }
  private void resultError(RequestContext ctx, String errorMsg) {
    ctx.setResponseStatusCode(401);
    ctx.setSendZuulResponse(false);
    ctx.setResponseBody(errorMsg);
  }
}

③定义组装类:

@Component
public class GatewayDirector {
  @Resource(name = "verificationBuild")
  private GatewayBuild gatewayBuild;
  public void direcot(RequestContext ctx, String ipAddres, HttpServletResponse response, HttpServletRequest request) {
    /**
     * 黑名单拦截
     */
    Boolean blackBlock = gatewayBuild.blackBlock(ctx, ipAddres, response);
    if (!blackBlock) {
      return;
    }
    /**
     * 参数验证
     */
    Boolean verifyMap = gatewayBuild.toVerifyMap(ctx, ipAddres, request);
    if (!verifyMap) {
      return;
    }
  }
}

④过滤器里使用:

/**
 * description: 网关拦截
 * create by: YangLinWei
 * create time: 2020/5/20 9:10 上午
 */
@Component
@Slf4j
public class GatewayFilter extends ZuulFilter {
  @Autowired
  private GatewayDirector gatewayDirector;
  @Override
  public Object run() throws ZuulException {
    RequestContext ctx = RequestContext.getCurrentContext();
    HttpServletRequest request = ctx.getRequest();
    HttpServletResponse response = ctx.getResponse();
    response.setContentType("UTF-8");
    // 1.获取ip地址
    String ipAddres = getIpAddr(request);
    if (StringUtils.isEmpty(ipAddres)) {
      resultError(ctx, "未能够获取到ip地址");
    }
    gatewayDirector.direcot(ctx, ipAddres, response, request);
    return null;
  }
  private void resultError(RequestContext ctx, String errorMsg) {
    ctx.setResponseStatusCode(401);
    ctx.setSendZuulResponse(false);
    ctx.setResponseBody(errorMsg);
  }
  @Override
  public boolean shouldFilter() {
    return true;
  }
  @Override
  public int filterOrder() {
    return 0;
  }
  /**
   * 在方法之前拦截
   * 
   * @return
   */
  @Override
  public String filterType() {
    return "pre";
  }
  /**
   * 获取Ip地址
   * 
   * @param request
   * @return
   */
  public String getIpAddr(HttpServletRequest request) {
    String ip = request.getHeader("X-Forwarded-For");
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
      ip = request.getHeader("Proxy-Client-IP");
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
      ip = request.getHeader("WL-Proxy-Client-IP");
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
      ip = request.getHeader("HTTP_CLIENT_IP");
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
      ip = request.getHeader("HTTP_X_FORWARDED_FOR");
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
      ip = request.getRemoteAddr();
    }
    return ip;
  }
}

④application.yml配置过滤的地址:

###服务启动端口号
server:
  port: 80
###服务注册到eureka地址
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8100/eureka
###服务名称(服务注册到eureka名称)
spring:
  application:
    name:  taodong-shop-basics-zuul
  ###数据库相关连接
  datasource:
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/taodong-gateway?useUnicode=true&characterEncoding=utf8&useSSL=false
### 配置网关反向代理
zuul:
  routes:
    api-a:
      ### 以 /api-weixin/访问转发到会员服务
      path: /api-weixin/**
      serviceId: taodong-shop-service-weixin
    api-b:
      ### 以 /api-member/访问转发到订单服务
      path: /api-member/**
      serviceId: taodong-shop-service-member
    api-c:
      ### 以 /api-member/访问转发到订单服务
      path: /api-pay/**
      serviceId: taodong-shop-service-pay
taodong-shop:
  zuul:
    swagger:
      document: '[ { "name": "taodong-shop-service-member", "location": "/taodong-shop-service-member/v2/api-docs",
                "version": "2.0" }, { "name": "taodong-shop-service-weixin", "location":
                "/taodong-shop-service-weixin/v2/api-docs", "version": "2.0" } ]'
### mybatis 日志打印
mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
logging:
  level:
    com.ylw.basics.zuul.mapper: debug

3.测试

浏览器访问:

http://127.0.0.1/api-pay/cratePayToken?payAmount=8882&orderId=20200513141452&userId=27&productName=玉米香肠,可以看到被拦截了。

数据库黑名单,改为允许访问:

可以看到能正常访问:

本文完!

目录
相关文章
|
12月前
|
存储 缓存 安全
某鱼电商接口架构深度剖析:从稳定性到高性能的技术密码
某鱼电商接口架构揭秘:分层解耦、安全加固、性能优化三维设计,实现200ms内响应、故障率低于0.1%。详解三层架构、多引擎存储、异步发布、WebSocket通信与全链路防护,助力开发者突破电商接口“三难”困境。
|
人工智能 安全 Cloud Native
Nacos 3.0 架构升级,AI 时代更安全的 Registry
随着Nacos3.0的发布,定位由“更易于构建云原生应用的动态服务发现、配置管理和服务管理平台”升级至“ 一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台 ”。
|
存储 设计模式 人工智能
AI Agent安全架构实战:基于LangGraph的Human-in-the-Loop系统设计​
本文深入解析Human-in-the-Loop(HIL)架构在AI Agent中的核心应用,探讨其在高风险场景下的断点控制、状态恢复与安全管控机制,并结合LangGraph的创新设计与金融交易实战案例,展示如何实现效率与安全的平衡。
2170 0
|
消息中间件 监控 前端开发
如何开发项目管理系统中的项目结项板块?(附架构图+流程图+代码参考)
在企业项目管理中,“项目结项”是关键环节,常因流程不清、文档不全、审批滞后等问题导致交付困难。本文介绍如何通过“项目结项”模块实现线上化管理,涵盖结项申请、审批流程、成果上传、权限控制等功能,帮助团队高效完成项目收尾,避免成果丢失与流程混乱。内容包括功能设计、业务流程、系统架构、数据库设计、核心代码实现、前端交互及优化建议,助力项目管理系统快速落地并稳定运行。
|
安全 测试技术 API
电商API接口开发:基础架构搭建全攻略
本文详细解析了电商API接口从零搭建基础架构的全流程。首先通过需求分析明确业务功能与接口规范,选定数据格式(如JSON)及通信方式(如RESTful)。接着在架构设计阶段选择合适的技术栈、数据库方案,并引入API网关实现统一管理。开发实现部分涵盖认证授权、数据访问、日志记录与异常处理等核心功能。安全防护则强调数据加密、传输安全及速率限制策略。测试优化阶段包括单元测试、集成测试、性能与安全测试,确保接口稳定性。最后通过工具生成清晰的API文档并实施版本控制,为开发者提供便利。整体流程系统化、模块化,助力打造高效、安全的电商API接口。
|
缓存 负载均衡 监控
微服务架构下的电商API接口设计:策略、方法与实战案例
本文探讨了微服务架构下的电商API接口设计,旨在打造高效、灵活与可扩展的电商系统。通过服务拆分(如商品、订单、支付等模块)和标准化设计(RESTful或GraphQL风格),确保接口一致性与易用性。同时,采用缓存策略、负载均衡及限流技术优化性能,并借助Prometheus等工具实现监控与日志管理。微服务架构的优势在于支持敏捷开发、高并发处理和独立部署,满足电商业务快速迭代需求。未来,电商API设计将向智能化与安全化方向发展。
665 102
|
12月前
|
缓存 Cloud Native 中间件
《聊聊分布式》从单体到分布式:电商系统架构演进之路
本文系统阐述了电商平台从单体到分布式架构的演进历程,剖析了单体架构的局限性与分布式架构的优势,结合淘宝、京东等真实案例,深入探讨了服务拆分、数据库分片、中间件体系等关键技术实践,并总结了渐进式迁移策略与核心经验,为大型应用架构升级提供了全面参考。
|
存储 监控 安全
132_API部署:FastAPI与现代安全架构深度解析与LLM服务化最佳实践
在大语言模型(LLM)部署的最后一公里,API接口的设计与安全性直接决定了模型服务的可用性、稳定性与用户信任度。随着2025年LLM应用的爆炸式增长,如何构建高性能、高安全性的REST API成为开发者面临的核心挑战。FastAPI作为Python生态中最受青睐的Web框架之一,凭借其卓越的性能、强大的类型安全支持和完善的文档生成能力,已成为LLM服务化部署的首选方案。
1518 3
|
存储 安全 前端开发
如何开发一套EHS 健康安全环境管理系统?(附架构图+流程图+代码参考)
本文介绍如何开发一套完整的EHS(健康、安全和环境)管理系统,涵盖系统核心模块、技术架构、数据库设计、前后端开发示例及上线建议,帮助企业提升安全管理效率与合规性。
|
数据挖掘 项目管理 Python
如何开发项目管理系统中的项目启动板块?(附架构图+流程图+代码参考)
本文介绍了项目管理系统中“项目启动”板块的设计与实现,涵盖功能模块、业务流程、开发技巧及效果展示,并提供代码参考和常见问题解答,助力企业高效搭建项目管理平台。