rest 验证demo

如何实现REST资源的输入验证

我正在使用的SaaS平台具有一个RESTful接口,该接口可以接受XML有效负载。

实施REST资源

对于像我们这样的Java商店,使用JAX-B从XML Schema生成JavaBean类是有意义的。 在像Jersey的JAX-RS环境中,使用JAX-B处理XML(和JSON)有效负载非常容易。

@Path("orders")
public class OrdersResource {@POST@Consumes({ "application/xml", "application/json" })public void place(Order order) {// Jersey marshalls the XML payload into the Order // JavaBean, allowing us to write type-safe code // using Order's getters and setters.int quantity = order.getQuantity();// ...}
}

(请注意,您不应使用这些通用媒体类型,但这是另一天的讨论。)

本文的其余部分假定使用JAX-B,但其要点也适用于其他技术。 无论您做什么,都不要使用XMLDecoder ,因为这对许多漏洞都是开放的 。

保护REST资源

假设订单的quantity用于结算,并且我们想防止人们输入负数来偷钱 。

我们可以通过输入验证 ( AppSec工具箱中最重要的工具之一)来做到这一点。 让我们看一下实现它的一些方法。

使用XML模式进行输入验证

我们可以依靠XML Schema进行验证 ,但是XML Schema只能验证那么多。

验证单个属性可能会很好,但是当我们要验证属性之间的关系时,事情变得很麻烦。 为了获得最大的灵活性,我们希望使用Java来表达约束。

更重要的是, 在REST服务中模式验证通常不是一个好主意

REST的主要目标是使客户端和服务器脱钩,以便它们可以分别发展。

如果我们根据模式进行验证,则发送新属性的新客户端将与无法理解该新属性的旧服务器发生冲突。 通常最好静默忽略您不了解的属性。

JAX-B做到了这一点,反之亦然:旧客户端未发送的属性最终为null 。 因此,新服务器必须小心以正确处理null值。

使用Bean验证的输入验证

如果我们不能使用模式验证,那么使用JSR 303 Bean验证又如何呢?

Jersey通过将jersey-bean-validation jar添加到您的类路径来支持Bean验证。

有一个非官方的Maven插件可以将Bean验证注释添加到JAX-B生成的类中,但是我宁愿使用更好的支持,并且可以与Gradle一起使用 。

因此,让我们扭转局势。 我们将手工制作JavaBean并从Bean生成XML模式以进行文档编制:

@XmlRootElement(name = "order")
public class Order {@XmlElement@Min(1)public int quantity;
}
@Path("orders")
public class OrdersResource {@POST@Consumes({ "application/xml", "application/json" })public void place(@Valid Order order) {// Jersey recognizes the @Valid annotation and// returns 400 when the JavaBean is not valid}
}

任何企图POST与非阳性数量的订单,现在将给予400 Bad Request状态。

现在假设我们要允许客户更改其挂单。 我们将使用PATCHPUT更新单个订单属性,例如数量:

@Path("orders")
public class OrdersResource {@Path("{id}")@PUT@Consumes("application/x-www-form-urlencoded")public Order update(@PathParam("id") String id, @Min(1) @FormParam("quantity") int quantity) {// ...}
}

我们也需要在此处添加@Min注释,这是重复的。 为了使这个DRY ,我们可以将quantity变成负责验证的类:

@Path("orders")
public class OrdersResource {@Path("{id}")@PUT@Consumes("application/x-www-form-urlencoded")public Order update(@PathParam("id") String id, @FormParam("quantity")Quantity quantity) {// ...}
}
@XmlRootElement(name = "order")
public class Order {@XmlElementpublic Quantity quantity;
}
public class Quantity {private int value;public Quantity() { }public Quantity(String value) {try {setValue(Integer.parseInt(value));} catch (ValidationException e) {throw new IllegalArgumentException(e);}}public int getValue() {return value;}@XmlValuepublic void setValue(int value) throws ValidationException {if (value < 1) {throw new ValidationException("Quantity value must be positive, but is: " + value);}this.value = value;}
}

我们需要JAX-B的公共no-arg构造函数,以能够将有效载荷解组到JavaBean中,而另一个构造函数则使用String来使@FormParam起作用。

setValue()抛出javax.xml.bind.ValidationException以便JAX-B将停止解组。 但是,Jersey看到异常时会返回500 Internal Server Error

我们可以通过使用异常映射器将验证异常映射到400状态代码来解决此问题。 在此过程中,让我们对IllegalArgumentException做同样的事情:

@Provider
public class DefaultExceptionMapper implements ExceptionMapper<Throwable> {@Overridepublic Response toResponse(Throwable exception) {Throwable badRequestException = getBadRequestException(exception);if (badRequestException != null) {return Response.status(Status.BAD_REQUEST).entity(badRequestException.getMessage()).build();}if (exception instanceof WebApplicationException) {return ((WebApplicationException)exception).getResponse();}return Response.serverError().entity(exception.getMessage()).build();}private Throwable getBadRequestException(Throwable exception) {if (exception instanceof ValidationException) {return exception;}Throwable cause = exception.getCause();if (cause != null && cause != exception) {Throwable result = getBadRequestException(cause);if (result != null) {return result;}}if (exception instanceof IllegalArgumentException) {return exception;}if (exception instanceof BadRequestException) {return exception;}return null;}}

域对象的输入验证

即使上面概述的方法对于许多应用程序都可以很好地工作,但从根本上来说还是有缺陷的。

乍一看, 领域驱动设计 (DDD)的支持者可能喜欢创建“ Quantity类的想法。

但是,“ Order和“ Quantity类不能为领域概念建模。 他们为REST表示建模。 这种区别可能很微妙,但很重要。

DDD处理领域概念,而REST处理这些概念的表示 发现了领域概念,但是设计了表示形式,并且需要进行各种折衷。

例如,集合REST资源可以使用分页来防止通过网络发送太多数据。 另一个REST资源可能结合了多个域概念,以使客户端-服务器协议不那么混乱。

REST资源甚至可能根本没有对应的域概念。 例如,一个POST可能返回202 Accepted并指向代表异步事务进度的REST资源。

域对象需要尽可能接近地捕获普遍存在的语言 ,并且必须权衡利弊才能使功能正常工作。

另一方面,在设计REST资源时,需要权衡满足非功能性要求,例如性能,可伸缩性和可扩展性。

这就是为什么我认为像RESTful Objects这样的方法不起作用的原因。 (出于类似原因,我不相信UI的Naked Objects 。)

在我们的资源表示形式的JavaBeans中添加验证意味着这些bean现在有两个更改的原因,这明显违反了“ 单一职责原则” 。

当仅将JAX-B JavaBeans用于REST表示并创建用于处理验证的单独域对象时,我们得到的架构将更加简洁 。

将验证放在域对象中是Dan Bergh Johnsson所谓的“ 域驱动的安全性” 。

在这种方法中,原始类型被值对象替代。 (甚至有人反对使用任何String 。)

起初,创建一个用于容纳单个整数的全新类似乎有些矫kill过正,但是我敦促您尝试一下。 您可能会发现,摆脱原始的迷恋甚至可以提供超出验证的价值。

你怎么看?

您如何在RESTful服务中处理输入验证? 您如何看待域驱动的安全性? 请发表评论。

参考: 如何从安全软件开发博客上的JCG合作伙伴 Remon Sinnema 获得REST资源的输入验证 。

翻译自: https://www.javacodegeeks.com/2013/08/how-to-implement-input-validation-for-rest-resources.html

rest 验证demo

rest 验证demo_如何实现REST资源的输入验证相关推荐

  1. 如何实现REST资源的输入验证

    如何实现REST资源的输入验证 我正在使用的SaaS平台具有一个RESTful接口,该接口可以接受XML有效负载. 实施REST资源 对于像我们这样的Java商店,使用JAX-B从XML Schema ...

  2. WEB应用安全之输入验证

    WEB2.0的普及,丰富了各类WEB产品.WEB交互能力的增强,也滋生出种类繁多的安全威胁,用户输入便成了万恶之源,不仅威胁用户信息安全,也给服务器.操作系统,甚至整个局域网带来灾难,因此,验证用户输 ...

  3. 常州SEO姜东:百度资源平台站点验证图文怎么做?

    搜索资源平台为站点提供三种验证方式:文件验证.html标签验证.CNAME验证.最为常见的就是文件验证,也是比较简单方便的一种方法. 1.文件验证 (1)登录百度搜索资源平台--点击用户中心--点击站 ...

  4. Struts2用户输入验证(6)

    10.6 小结 Struts2框架下的用户输入验证分为三种方式:1. 编程方式下的验证 2. 配置方式下的验证 3.注解方式下的验证.          如果在Struts2项目下存在多种验证方式,其 ...

  5. 3.Struts2的输入验证

    l          当类型转换成功以后,struts2将进行输入验证 若要进行输入验证则你的action必须继承ActionSupport类,实现其validate方法 在方法中调用addFiled ...

  6. Struts2的输入验证(三)-短路验证与非字段验证

    一.短路验证 若对一个字段使用多个验证器,默认情况下会执行所有的验证.若希望前面的验证器验证没有通过,后面的就不再验证,可以使用短路验证. 1)对同一个字段内的多个验证器,如果一个短路验证器验证失败, ...

  7. 【Block-Level Verification】 芯片开发通识_验证目标_ 验证语言_ 验证职业前景 _挑战和瓶颈_验证周期_功能描述文档_验证计划_回归测试_硅后测试_逃逸分析...

    SystemVerilog验证通识 1. 芯片开发概述 不同于通用电路,专用集成电路为了专门解决或者优化相关工程问题,例如专用算法的电路实现,如芯片里加入人工智能处理单元,为CPU\GPU减负,目的是 ...

  8. 计算机安全用户身份验证,Windows 10 (网络安全 LAN 管理器身份验证) - Windows security | Microsoft Docs...

    网络安全: LAN 管理器身份验证级别 04/19/2017 本文内容 适用范围 Windows 10 介绍网络安全的最佳方案.位置.值.策略管理和安全注意事项 :LAN 管理器身份验证级别 安全策略 ...

  9. 两台服务器身份验证,详解三种不同的身份验证协议

    本文最初发布于devever.net网站,经原作者授权由InfoQ中文站翻译并分享. 现在,身份验证协议的数量快赶上应用程序协议,结果,这个领域很容易让人困惑. 最容易把人搞糊涂的是,很少有人注意到这 ...

最新文章

  1. idea打开web项目之后一直闪烁
  2. 技术图文:匿名方法是怎样演变为Lambda表达试的?
  3. 深度学习100例 | 第53天:用YOLOv5训练自己的数据集(超级详细完整版)
  4. NET平台下Web树形结构程序设计
  5. [实战演练]腾讯2013年校招软件开发类笔试题目(选择题部分)
  6. JQuery validate表單驗證
  7. 模拟输入(ADC-A0)
  8. flux java_Java反应式框架Reactor中的Mono和Flux
  9. oracle中怎么算奇数,oracle - 如何在oracle中获取奇数列 - SO中文参考 - www.soinside.com...
  10. Ubuntu 16.04中iptables的工具简介(iptables/iptables-restore/iptables-xml/iptables-apply/iptables-save)...
  11. C++中的取地址符()
  12. 技术分享 — Java如何实现证件照换底色
  13. 四、Mosquitto 高级应用之用户配置
  14. 强改微信内置浏览器——让x5内核滚粗
  15. ns3中PointToPointDumbbellHelper类的引入方法(哑铃型网络模拟)
  16. 载录Windows 9X、2000、XP、2003所有注册表设置
  17. JackKnife开发专题-方便快捷的IOC框架
  18. 腾讯云服务器1M带宽下载速度怎么样?慢不慢?
  19. lineWithFocusChart(python - nvd3)
  20. PMP备考指南之第十一章:项目风险管理

热门文章

  1. [51NOD1847]奇怪的数学题(杜教筛+min_25筛+第二类斯特林数)
  2. VAE(变分自编码器)学习笔记
  3. Maven的pom.xml文件详解------The Basics
  4. 这些分布式事务的解决方案,你都知道吗
  5. MySQL extract()函数
  6. 漫画:什么是一致性哈希
  7. ​凌云KTV点歌系统功能简介
  8. 购物车的功能——JS源码
  9. 遍历HashMap的四种方法
  10. vo listVO paggerHelper mapper使用原则