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

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模式 我们可以依靠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;}}

域对象的输入验证

http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-ebook/dp/B00794TAUG/ref=tmm_kin_title_0?ie=UTF8&qid=1376856556&sr=1-1 即使上面概述的方法对于许多应用程序都可以很好地工作,但从根本上来说还是有缺陷的。

乍一看, 领域驱动设计 (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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/347205.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

校园点餐系统:点餐、食堂管理、商户管理和菜品管理(Java和MySQL)

微信公众号&#xff1a;创享日记 发送关键词&#xff1a;校园点餐系统 获取报告数据库设计说明项目源码源文件工程文件 1 实验环境 操作系统&#xff1a;Windows 10&#xff0c;主要开发工具&#xff1a;PowerDesign&#xff0c;MySQL&#xff0c;Eclipse 2 实验过程 2.1 系统…

病情预测:指示病情程度、预测病情指标(深度学习和Python)

前些天发现了十分不错的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;没有广告&#xff0c;分享给大家&#xff0c;大家可以自行看看。&#xff08;点击跳转人工智能学习资料&#xff09; 微信公众号&#xff1a;创享日记 发送关键词&#xff1a;病情…

QueryDSL中包含通配符的字符串的精确匹配

在我们最近的一个项目中&#xff0c;我们的客户要求一个搜索字段&#xff0c;该字段可以搜索名字&#xff0c;姓氏和电子邮件地址&#xff0c;唯一的通配符是星号“ *”&#xff0c;表示部分匹配。 听起来很简单&#xff0c;但它使我们陷入了混乱。 在我们的项目中&#xff0c;…

邮件系统(基于SMTP协议和POP3协议-C语言实现)

前些天发现了十分不错的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;没有广告&#xff0c;分享给大家&#xff0c;大家可以自行看看。&#xff08;点击跳转人工智能学习资料&#xff09; 微信公众号&#xff1a;创享日记 发送关键词&#xff1a;邮件…

arp、ethernet、icmp、udp、ip协议的C语言实现(计算机网络协议栈实验)

前些天发现了十分不错的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;没有广告&#xff0c;分享给大家&#xff0c;大家可以自行看看。&#xff08;点击跳转人工智能学习资料&#xff09; 微信公众号&#xff1a;创享日记 发送关键词&#xff1a;协议…

jpa获取session_JPA 2 | 获取联接以及我们是否应该使用它们

jpa获取session介绍 最近&#xff0c;我一直在与JPA 2中的FETCH JOINS一起使用&#xff0c;以期从数据库中急切地获取数据&#xff0c;并且我学到了很多关于为什么在日常操作中应避免使用Fetch Joins的知识。 今天的博客文章谈论了我在Fetch上的经历和学习&#xff08;主要基于…

CPU设计(单周期和流水线)

前些天发现了十分不错的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;没有广告&#xff0c;分享给大家&#xff0c;大家可以自行看看。&#xff08;点击跳转人工智能学习资料&#xff09; 微信公众号&#xff1a;创享日记 发送关键词&#xff1a;cpu …

使用AWS Lambdas扩展技术堆栈

面对现实吧。 调试性能问题很困难&#xff0c;但更难解决。 假设您发现了令人反感的代码&#xff0c;这些代码正在拖慢您的应用的运行速度。 最终会有一段时间&#xff0c;您发现该代码减速是同步的或线性执行的。 解决这些有问题的代码段的最有效方法之一是将最重的工作负载委…

前馈-反馈控制系统设计(过程控制课程设计matlab/simulink)

前些天发现了十分不错的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;没有广告&#xff0c;分享给大家&#xff0c;大家可以自行看看。&#xff08;点击跳转人工智能学习资料&#xff09; 微信公众号&#xff1a;创享日记 发送关键词&#xff1a;前馈…

感应电机直接转矩控制系统的设计与仿真(运动控制matlab/simulink)

前些天发现了十分不错的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;没有广告&#xff0c;分享给大家&#xff0c;大家可以自行看看。&#xff08;点击跳转人工智能学习资料&#xff09; 微信公众号&#xff1a;创享日记 发送关键词&#xff1a;直接…

【2】C++语法与数据结构之MFC_CList学生管理系统_链表内排序_函数指针

MFC中CList类库的遍历 #include <iostream> #include "List.h" using namespace std; void main() {CList list;list.AddHead(33);list.AddHead(88);list.AddHead(99);POSITION pos list.GetHeadPosition();cout << "正向&#xff1a;" <…

neo4j cypher_neo4j / cypher:悬挂查询参数

neo4j cypher一直以来&#xff0c;我一直在使用neo4j的密码查询语言&#xff0c; 迈克尔一直在告诉我在查询中使用参数&#xff0c;但是查询的性能始终可以接受&#xff0c;因此我没有必要。 但是&#xff0c;最近我正在研究一个数据集&#xff0c;并使用类似于以下的代码创建了…

双容水箱液位模糊PID控制系统设计与仿真(Matlab/Simulink)

前些天发现了十分不错的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;没有广告&#xff0c;分享给大家&#xff0c;大家可以自行看看。&#xff08;点击跳转人工智能学习资料&#xff09; 微信公众号&#xff1a;创享日记 发送&#xff1a;双容模糊 获…

基于单片机步进电机控制器设计(正转反转指示灯挡位)

前些天发现了十分不错的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;没有广告&#xff0c;分享给大家&#xff0c;大家可以自行看看。&#xff08;点击跳转人工智能学习资料&#xff09; 微信公众号&#xff1a;创享日记 发送&#xff1a;单片机步进…

【3】C++语法与数据结构之MFC_CList学生管理系统_链表外排序_函数指针

注意&#xff1a;此时排序规则函数定义为全局函数 C中定义CStudent类 文件名&#xff1a;Student.h #pragma once #include <afxtempl.h> typedef struct SUser {int nNumb;char sName[20];float fMath; }DATA;typedef bool(*BY_FUNC)(DATA& q,DATA& m);class…

Java中Long到Int的精确转换

JDK 8附带所有令人眼前一亮的 东西 &#xff08; lambda表达式 &#xff0c; 流 &#xff0c; Optional &#xff0c;新的Date / Time API等&#xff09;来分散我的注意力 &#xff0c;我并没有过多注意添加方法Math.toIntExact&#xff08;&#xff09; 。 但是&#xff0c;这…

基于单片机的交通灯控制系统设计

前些天发现了十分不错的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;没有广告&#xff0c;分享给大家&#xff0c;大家可以自行看看。&#xff08;点击跳转人工智能学习资料&#xff09; 微信公众号&#xff1a;创享日记 发送&#xff1a;单片机交通…

【4】C++语法与数据结构之自己实现MFC的CList类库_学生管理系统

本文通过自己实现的CList双向链表数据结构来完成学生管理系统&#xff0c;同样采用链表外排序。 注意&#xff1a;此时排序规则函数仍然定义为全局函数 自己定义CList类 文件名&#xff1a;List.h -注意&#xff1a; POSITION不是VS默认的类型&#xff0c;而是重新定义为vo…

36个精美完整网站网页完整源码HTML+CSS+JS

以下列举前9个效果图&#xff0c;源码详见微信公众号下载 ①效果图 ②效果图 ③效果图 ④效果图 ⑤效果图 ⑥效果图 ⑦效果图 ⑧效果图 ⑨效果图 微信公众号&#xff1a;创享日记 发送&#xff1a;36 获取全部完整源码&#xff08;打开.html文件均即可用&…

【5】C++语法与数据结构之STL_list学生管理系统_链表内排序_函数指针

本文通过STL类库的list数据结构来完成学生管理系统&#xff0c;采用链表内排序&#xff0c;通过list类库自带sort函数进行排序。 注意&#xff1a;此时排序规则函数定义为类静态成员函数&#xff0c;等价于全局函数函数指针定义为 BY_FUNC ps[] { CStudent::byNumb,CStudent:…