SpringBoot的开箱即用功能,大大降低了上手一个WEB应用的门槛,友好的REST接口支持,在SpringCloud微服务体系中可编程性大大提高,本篇基于一个面向企业调用方用户的WEB API项目,基于SpringBoot来构建,简单看下接口的安全性模块设计。

主要借助于基于AOP技术来进行接口的安全防护,在SpringBoot下直接引入spring-boot-starter-aop即可使用。

1、在Pom中引入AOP配置


  1. <dependency>  

  2.     <groupId>org.springframework.boot</groupId>  

  3.     <artifactId>spring-boot-starter-aop</artifactId>  

  4. </dependency>

2、编写对应处理类即可,通过@Order(n)设置合法的校验顺序。如LogAspect


  1. @Aspect

  2. @Order(1)

  3. @Component

  4. public class LogAspect {

  5.    private Logger logger=Logger.getLogger(LogAspect.class);

  6.    @Pointcut("execution(public * com.wey.say.api.*.* (..))")

  7.    public void apiLogAspect() {

  8.    }

  9.    @Before("apiLogAspect()")

  10.    public void dobefore(JoinPoint joinPoint) {

  11.        RequestAttributes ra = RequestContextHolder.getRequestAttributes();

  12.        ServletRequestAttributes sra = (ServletRequestAttributes) ra;

  13.        HttpServletRequest request = sra.getRequest();

  14.        // 使用log4j的MDC及NDC特性,识别请求方的IP及调用资料,输出到日志中

  15.        MDC.put("uri", request.getRequestURI());

  16.        NDC.push(request.getRemoteAddr());

  17.        // 记录下请求内容

  18.        logger.info("HTTP_METHOD : " + request.getMethod());

  19.        logger.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "."

  20.                + joinPoint.getSignature().getName());

  21.        logger.info("ARGS : " + Arrays.toString(joinPoint.getArgs()));

  22.        NDC.pop();

  23.        NDC.remove();

  24.        MDC.get("uri");

  25.        MDC.remove("uri");

  26.    }

  27.    @AfterReturning(returning = "ret", pointcut = "apiLogAspect()")

  28.    public void doAfterReturning(Object ret) throws Throwable {

  29.        // 处理完请求,返回内容

  30.        logger.info("RESPONSE : " + ret);

  31.    }

下面进入此系统关键的安全设计模块,由于是面向企业级接口调用用户,与面向大众的接口稍微有些不同,分为以下几个方面。

  • 1、详细日志记录,凡请求过来均进行记录,便于后期识别非法请求的防范依据

参考上文中实现方式,可以再细化。进行日志的收集分析,后期分析接口的调用频率等进一步需求。

  • 2、白名单限制,仅接受特定系统的请求响应,调用方的IP地址需要在本系统中报备,否则无法调用。

不采用黑名单机制,主要原因在于未知的IP量太大,只能采用允可的方式,成本最小,效果也最好。

  • 3、调用法身份合法性验证,即便是白名单用户,也需要进行验证,确保用户真正合法。主要验证此请求是否确实来自于某一调用法,而非伪造的用户请求。

常见做法:为调用方设置一个唯一标识和一个密钥,接口到请求时校验这两者的合法性。

  • 4、基于HmacSHA1算法进行请求参数完整性验证,主要用于检测传输过程中参数是否被篡改。

也可以采用的简单的MD5验签,效率更高。

  • 5、防重放攻击,即可通过了前4个步骤,不排除利用合法请求,暴力调用的情况。在验证过程中增加时间戳项目,校验调用时间是否在允许范围内,比如1分钟之内。(案例:QQ第三方登陆在校验调用时间与服务时间时,时间差合理范围内,即便不一致,也可以使用)

CSRF的问题必须要重视,可以进行很强大的重放攻击。当然还有其它的如DOS攻击等。

  • 6、流量控制。比较熟知的例子就是微信开放平台暴露的接口,DOC中明显指出某一接口一天内允许调用的次数,超过限制将无法响应。考虑到实际企业调用的情况,我们同样可以针对某一调用方某一请求进行限制

可借助Guava中对应RateLimiter模块功能,也可借助Redis高效响应机制自己设计,以调用方id+接口名称为KEY,设置接口调用上限即可,按天实时更新数据增量。

以上基本上可以算是个完整的安全防范过程,当然还是需要借助运维手段,在外层进行安全防范,比如WAF等,也可以在更高级处进行防范,比如网关接入层。

扩展阅读:

歪脖贰点零关注程序员个人成长

基于SpringBoot的WEB API项目的安全设计的更多相关文章

  1. 基于SpringBoot的Web API快速开发基础框架

    其实还是很因为懒,才会有这个案例项目的产生,每次开启一个终端的小服务都要整理一次框架,造成重复的.不必要的.缺乏创造性的劳动,SO,本着可以用.用着简单的原则上传代码到Github,希望有需要的朋友直 ...

  2. 基于springboot的web项目最佳实践

    springboot 可以说是现在做javaweb开发最火的技术,我在基于springboot搭建项目的过程中,踩过不少坑,发现整合框架时并非仅仅引入starter 那么简单. 要做到简单,易用,扩展 ...

  3. 使用IDEA新建基于SpringBoot的Web项目(超详细)

    目前java的开发很多Learner都慢慢的学习使用IDEA这款工具,个人觉得其实相比Eclipse来说差不多,个人习惯的问题,但是我还是推荐IDEA这款工具.虽然它目前是收费的,但相信网上的各种破解 ...

  4. Web API项目中使用Area对业务进行分类管理

    在之前开发的很多Web API项目中,为了方便以及快速开发,往往把整个Web API的控制器放在基目录的Controllers目录中,但随着业务越来越复杂,这样Controllers目录中的文件就增加 ...

  5. 基于Attribute的Web API路由设置

    路由对于MVC应用程序来说都是至关重要的一个部门,不管是asp.net mvc或者Ruby on Rails(当然还有其它的,我只熟悉这两个:) )  asp.net mvc自带的路由配置是在Glob ...

  6. 基于ASP.NET WEB API实现分布式数据访问中间层(提供对数据库的CRUD)

    一些小的C/S项目(winform.WPF等),因需要访问操作数据库,但又不能把DB连接配置在客户端上,原因有很多,可能是DB连接无法直接访问,或客户端不想安装各种DB访问组件,或DB连接不想暴露在客 ...

  7. 对一个前端使用AngularJS后端使用ASP.NET Web API项目的理解(3)

    chsakell分享了一个前端使用AngularJS,后端使用ASP.NET Web API的项目. 源码: https://github.com/chsakell/spa-webapi-angula ...

  8. 对一个前端使用AngularJS后端使用ASP.NET Web API项目的理解(2)

    chsakell分享了一个前端使用AngularJS,后端使用ASP.NET Web API的项目. 源码: https://github.com/chsakell/spa-webapi-angula ...

  9. Web API(三):创建Web API项目

    在本篇文章中将讲解如何使用Visual Studio创建一个新的ASP.NET Web API项目. 在Visual Studio中有两种方式用于创建Web API项目: 1.创建带MVC的Web A ...

随机推荐

  1. 最好的方式是用VirtualAlloc分配虚拟内存,它既不是在堆也不是在栈,而是直接在进程的地址空间中保留一块内存

    申请效率的比较 栈:由系统自动分配,速度较快.但程序员是无法控制的. 堆:是由new分配的内存,最好的方式是用VirtualAlloc分配虚拟内存,它既不是在堆也不是在栈,而是直接在进程的地址空间中保 ...

  2. Cordova页面加载外网图片失败,Refused to load the image

    原文:Cordova页面加载外网图片失败,Refused to load the image 1.使用Cordova页面加载外网图片失败,抛出异常 Refused to load the image ...

  3. wpf-MVVM界面自适应:界面自适应及字体自适应

    原文:wpf-MVVM界面自适应:界面自适应及字体自适应 1,界面自适应 界面先划分Region,每个填充Region的View不设置Width属性,即可按照Region划分的比例,自适应屏幕分辨率 ...

  4. .net的数据类型说明

    C#提供称为简单类型的预定义结构类型集,简单类型通过保留字标识, 而这些保留字只是System命名空间中预定义结构类型的别名. 保留字与预定义结构类型的对应如下: 保留字 预定义结构类型 sbyte ...

  5. UAP开发错误之The given System.Uri cannot be converted into a Windows.Foundation.Uri(windows phone背景更换)

    今天博主在开发一款windows phone应用时,希望实现app背景的更换,思路很简单.使用ApplicationDataContainer容器存储我的图片路径,每次载入应用时读取这个路径以决定我用 ...

  6. 记一次 qW3xT.4,解决挖矿病毒。

    最近感觉我的服务器特别卡,打开数据库都半天,刚开始以为网咯不好也没太在意. 利用top命令: 这时候问题出来了,最高cpu占用100%,那我用啥??? 根据进程id 一看究竟,ps -ef|grep ...

  7. Java基础(五) final关键字浅析

    前面在讲解String时提到了final关键字,本文将对final关键字进行解析. static和final是两个我们必须掌握的关键字.不同于其他关键字,他们都有多种用法,而且在一定环境下使用,可以提 ...

  8. python requests模块session的使用建议及整个会话中的所有cookie的方法

    话不多说,直接上代码 测试代码 服务端 下面是用flask做的一个服务端,用来设置cookie以及打印请求时的请求头 # -*- coding: utf-8 -*- from flask import ...

  9. OpenProj打开不了或者提示”Failed to load Java VM Library”的错误的解决方案

    一.双击打开OpenProj.exe没反应的解决方案: 1) 修改OpenProj1.4.0.ini,将Maximum Version=any改为Maximum Version=1.7,保存. 2)这 ...

  10. Verilog写一个对数计算模块Log2(x)

    网上一个能用的也没有,自己写一个把. 1.计算原理:  整数部分 网上找到了一个c语言的计算方法如下: int flog2(float x) { return ((unsigned&)x> ...