保护Spring Boot Data Rest应用程序中的JSON-PATCH路径

时间:2017-03-03 23:17:48

标签: java spring spring-mvc json-patch

我使用了漂亮的PATCH设置并启用了path方法。一切正常,但我有一个安全问题,并想知道减轻它的推荐方法是什么。

问题是comments article允许从不同的端点更新可访问的实体。所以,假设我有一个PATCH http://some.domain.foo/api/comments/1234 Content-Type: application/json-patch+json [ { "op": "replace", "path": "/article/title", "value": "foobar2" } ] 端点和一个<result> <data> <s id="16" n="Ice Hockey"> <cat id="1060" n="Swedish SHL"> <m id="1335939" n="Farjestad BK v Hv71" mid="804927" dt="2017-03-04T15:00"> <t id="1" n="Single Match"> <l id="23578344" i="0" o="3.9">Draw</l> <l id="23578343" i="1" o="2.35">Farjestad BK</l> <l id="23578342" i="2" o="2.45">Hv71</l> </t> <t id="2" n="Moving Line"> <l id="23578350" i="1" o="3.5" p="-1.5">Farjestad BK (-1.5)</l> <l id="23578349" i="2" o="1.25" p="1.5">Hv71 (+1.5)</l> </t> <t id="4" n="Point Score"> <l id="23578348" i="1" o="1.8" p="4.5">Game Total OVER 4.5</l> <l id="23578347" i="2" o="2" p="4.5">Game Total UNDER 4.5</l> </t> </m> </cat> <cat id="1062" n="Finnish SM-liiga"> <m id="1335991" n="Jukurit v Kookoo" mid="804993" dt="2017-03-04T15:00"> <t id="1" n="Single Match"> <l id="23579183" i="0" o="4">Draw</l> <l id="23579182" i="1" o="1.8">Jukurit</l> <l id="23579181" i="2" o="3.5">Kookoo</l> </t> <t id="2" n="Moving Line"> <l id="23579189" i="1" o="2.55" p="-1.5">Jukurit (-1.5)</l> <l id="23579188" i="2" o="1.45" p="1.5">Kookoo (+1.5)</l> </t> <t id="4" n="Point Score"> <l id="23579187" i="1" o="1.9" p="4.5">Game Total OVER 4.5</l> <l id="23579186" i="2" o="1.8" p="4.5">Game Total UNDER 4.5</l> </t> </m> <m id="1335996" n="Ässät Pori v HPK Hämeenlinna" mid="804998" dt="2017-03-04T15:00"> <t id="1" n="Single Match"> <l id="23579278" i="0" o="3.9">Draw</l> <l id="23579277" i="1" o="2.25">Ässät Pori</l> <l id="23579276" i="2" o="2.65">HPK Hämeenlinna</l> </t> <t id="2" n="Moving Line"> <l id="23579284" i="1" o="3.2" p="-1.5">Ässät Pori (-1.5)</l> <l id="23579283" i="2" o="1.3" p="1.5">HPK Hämeenlinna (+1.5)</l> </t> <t id="4" n="Point Score"> <l id="23579282" i="1" o="1.9" p="4.5">Game Total OVER 4.5</l> <l id="23579281" i="2" o="1.8" p="4.5">Game Total UNDER 4.5</l> </t> </m> </cat> </s> </data> 端点。每条评论与其文章都有一对一的关联。有权编辑评论的用户可以执行以下操作:

    INSERT INTO dbo.Intertops(SportID, SportName,CatID, CatName, MatchID, MatchName,
    MatchMID, MatchDate, TypeID, TypeName, LineID, LineIndex, LineOdds, Teams) 


SELECT 
SportID = Hockey.value('@id[1]', 'int'),
SportName = Hockey.value('@n[1]', 'varchar(20)'),
CatID = Hockey.value('cat[1]/@id', 'int'),
CatName = Hockey.value('cat[1]/@n', 'varchar(20)'),
MatchID = Hockey.value('(cat/m)[1]/@id', 'int'),
MatchName = Hockey.value('(cat/m)[1]/@n', 'varchar(50)'),
MatchMID = Hockey.value('(cat/m)[1]/@mid', 'int'),
MatchDate = Hockey.value('(cat/m)[1]/@dt', 'varchar(20)'),
TypeID = Hockey.value('(cat/m/t)[1]/@id', 'int'),
TypeName = Hockey.value('(cat/m/t)[1]/@n', 'varchar(20)'),
LineID = Hockey.value('(cat/m/t/l)[1]/@id', 'int'),
LineIndex = Hockey.value('(cat/m/t/l)[1]/@i', 'int'),
LineOdds = Hockey.value('(cat/m/t/l)[1]/@o', 'float'),
Teams = Hockey.value('(cat/m/t/l)[1]', 'varchar(20)')

FROM ( 
SELECT CAST(x AS XML)
FROM OPENROWSET(
 BULK 'C:\filer\intertops.xml',
 SINGLE_BLOB) AS T(x)
 ) AS T(x)
CROSS APPLY x.nodes('//result/data/s') AS X(Hockey);

从而改变了文章的标题!!

显然,这不是一件好事。

在这种情况下,对于API的其他部分,与&#34;文章&#34;的关联;需要可穿越。但它必须是只读的。

那么......我如何在Spring中实现这一目标?

拦截请求? 实现处理程序方法? 从头开始编写我自己的Controller?

谢谢!

1 个答案:

答案 0 :(得分:5)

似乎spring-data-rest上的当前实现将路径转换为SpEL以直接在bean上应用值。请参阅this

考虑以下选项:

  • 使用 json-merge PATCH请求代替json-patch发送部分更新(使用&#34; application / json&#34;或&#34; application / merge-patch + json&# 34;内容类型)。这将尊重@JsonIgnore和其他杰克逊注释,并以不同方式对待协会。
  • 您可以完全禁用&#34; json-patch + json&#34; ,例如添加安全过滤器
  • 如果您仍然需要,您可以随时创建自定义json-patch实现
  • 使用不依赖于JPA的应用程序级联接,即仅公开链接实体的ID并在ResourceProcessor中提供自定义链接。

此外,如果您使用JPA并Comment.article使用@ManyToOne进行注释,请确保关联时没有级联。即使使用补丁修改了文章对象,它也不会与评论一起保存。