Spring认证中国教育管理中心-Spring Data REST框架教程三

本文介绍了Spring Data REST框架的高级特性,包括如何排序查询结果、定制对象映射以适应复杂模型,以及如何使用Jackson自定义序列化器和反序列化器。学习者将学会如何处理投影和简化资源视图,以提高API的灵活性和易用性。

原标题:Spring认证中国教育管理中心-Spring Data REST框架教程三(Spring中国教育管理中心

5.2.排序

Spring Data REST 识别使用存储库排序支持的排序参数。

要根据特定属性对结果进行排序,请添加一个sortURL 参数,其中包含要对结果进行排序的属性的名称。您可以通过将逗号 ( ,)附加到属性名称加上asc或来控制排序的方向desc。以下将使用在名称以字母“K”开头的所有实体findByNameStartsWith上定义的查询方法,并添加排序数据,以降序对属性上的结果进行排序:
PersonRepositoryPersonname

curl -v "http://localhost:8080/people/search/nameStartsWith?name=K&sort=name,desc"

要按多个属性对结果进行排序,请sort=PROPERTY根据需要继续添加尽可能多的参数。它们Pageable按照它们在查询字符串中出现的顺序添加到中。结果可以按顶级和嵌套属性排序。使用属性路径表示法来表达嵌套排序属性。不支持按可链接的关联(即顶级资源的链接)排序。

6.领域对象表示(Object Mapping)

Spring Data REST 返回Accept与 HTTP 请求中指定的类型相对应的域对象的表示。

目前,仅支持 JSON 表示。将来可以通过添加适当的转换器并使用适当的内容类型更新控制器方法来支持其他表示类型。

有时,Spring Data REST 的行为ObjectMapper(已专门配置为使用可以将域对象转换为链接并再次返回的智能序列化程序)可能无法正确处理您的域模型。您可以通过多种方式构建数据,以至于您可能会发现自己的域模型没有正确转换为 JSON。在这些情况下,尝试以通用方式支持复杂的域模型有时也是不切实际的。有时,根据复杂性,甚至不可能提供通用解决方案。

6.1.向 Jackson 的 ObjectMapper 添加自定义序列化器和反序列化器

为了适应最大比例的用例,Spring Data REST 非常努力地尝试正确呈现您的对象图。它尝试将非托管 bean 序列化为普通 POJO,并尝试在必要时创建指向托管 bean 的链接。但是,如果您的域模型不容易读取或写入纯 JSON,您可能需要使用您自己的自定义映射、序列化器和反序列化器来配置 Jackson 的 ObjectMapper。

6.1.1.抽象类注册

您可能需要挂钩的一个关键配置点是在域模型中使用抽象类(或接口)时。默认情况下,Jackson 不知道为接口创建什么实现。考虑以下示例:

@Entity
public class MyEntity {
  @OneToMany
  private List<MyInterface> interfaces;
}

在默认配置中,Jackson 不知道在向导出器发布新数据时要实例化哪个类。这是您需要通过注释或(更干净地)通过使用Module.

要将您自己的 Jackson 配置添加到ObjectMapperSpring Data REST 使用的配置中,请覆盖该
configureJacksonObjectMapper方法。该方法被传递一个ObjectMapper实例,该实例具有处理序列化和反序列化PersistentEntity对象的特殊模块。您也可以注册自己的模块,如以下示例所示:

@Override
protected void configureJacksonObjectMapper(ObjectMapper objectMapper) {

  objectMapper.registerModule(new SimpleModule("MyCustomModule") {

    @Override
    public void setupModule(SetupContext context) {
      context.addAbstractTypeResolver(
        new SimpleAbstractTypeResolver()
          .addMapping(MyInterface.class, MyInterfaceImpl.class));
    }
  });
}

一旦您可以访问 中的SetupContext对象Module,您就可以做各种很酷的事情来配置 Jackson 的 JSON 映射。您可以Module在Jackson 的 wiki上阅读有关实例如何工作的更多信息。

6.1.2.为域类型添加自定义序列化程序

如果您想以特殊方式序列化或反序列化域类型,您可以使用 Jackson 注册您自己的实现,ObjectMapperSpring Data REST 导出器会透明地正确处理这些域对象。要从您的setupModule方法实现中添加序列化程序,您可以执行以下操作:

@Override
public void setupModule(SetupContext context) {

  SimpleSerializers serializers = new SimpleSerializers();
  SimpleDeserializers deserializers = new SimpleDeserializers();

  serializers.addSerializer(MyEntity.class, new MyEntitySerializer());
  deserializers.addDeserializer(MyEntity.class, new MyEntityDeserializer());

  context.addSerializers(serializers);
  context.addDeserializers(deserializers);
}

7. 预测和摘录

Spring Data REST 提供了您导出的域模型的默认视图。但是,有时,您可能出于各种原因需要更改该模型的视图。本节介绍如何定义预测和摘录以提供简化和简化的资源视图。

7.1.预测

考虑以下域模型:

@Entity
public class Person {

  @Id @GeneratedValue
  private Long id;
  private String firstName, lastName;

  @OneToOne
  private Address address;
  …
}

Person上例中的对象有几个属性:

  • id 是主键。
  • firstName和lastName是数据属性。
  • address 是指向另一个域对象的链接。

现在假设我们创建了一个对应的仓库,如下:

interface PersonRepository extends CrudRepository<Person, Long> {}

默认情况下,Spring Data REST 导出此域对象,包括其所有属性。firstName并lastName作为它们的纯数据对象导出。关于address属性有两个选项。一种选择是还为Address对象定义一个存储库,如下所示:

interface AddressRepository extends CrudRepository<Address, Long> {}

在这种情况下,Person资源将address属性呈现为其对应Address资源的 URI 。如果我们在系统中查找“Frodo”,我们可能会看到这样的 HAL 文档:

{
  "firstName" : "Frodo",
  "lastName" : "Baggins",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/persons/1"
    },
    "address" : {
      "href" : "http://localhost:8080/persons/1/address"
    }
  }
}

还有另一种方法。如果Address域对象没有自己的存储库定义,Spring Data REST 会在Person资源中包含数据字段,如以下示例所示:

{
  "firstName" : "Frodo",
  "lastName" : "Baggins",
  "address" : {
    "street": "Bag End",
    "state": "The Shire",
    "country": "Middle Earth"
  },
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/persons/1"
    }
  }
}

但是,如果您根本不想要address细节怎么办?同样,默认情况下,Spring Data REST 导出其所有属性(除了id)。您可以通过定义一个或多个投影为 REST 服务的使用者提供替代方案。以下示例显示了不包含地址的投影:

@Projection(name = "noAddresses", types = { Person.class }) 
interface NoAddresses { 

  String getFirstName(); 

  String getLastName(); 
}

该@Projection注释将其标记为一个投影。该name属性提供了投影的名称,稍后我们将更详细地介绍它。该types属性的目标这个投影仅适用于Person对象。

它是一个 Java 接口,使其具有声明性。

它导出firstName.

它导出lastName.

Spring认证中国教育管理中心-Spring Data REST框架教程三

该NoAddresses投影只有firstName和 的吸气剂lastName,这意味着它不提供任何地址信息。假设您有一个单独的资源存储库Address,Spring Data REST 的默认视图与之前的表示略有不同,如以下示例所示:

{
  "firstName" : "Frodo",
  "lastName" : "Baggins",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/persons/1{?projection}", 
      "templated" : true 
    },
    "address" : {
      "href" : "http://localhost:8080/persons/1/address"
    }
  }
}

此资源有一个新选项:{?projection}。

该selfURI是URI模板。

要查看资源的投影。

Spring认证中国教育管理中心-Spring Data REST框架教程三

提供给projection查询参数的值与 中指定的值相同@Projection(name = "noAddress")。它与投影界面的名称无关。

您可以有多个投影。

请参阅投影以查看示例项目。我们鼓励您尝试使用它。

Spring Data REST 查找投影定义如下:

@Projection在与您的实体定义(或其子包之一)相同的包中找到的任何接口都已注册。

您可以使用 手动注册投影
RepositoryRestConfiguration.getProjectionConfiguration().addProjection(…)。

无论哪种情况,投影界面都必须有@Projection注释。

7.1.1.寻找现有的预测

Spring Data REST 公开了Application-Level Profile Semantics (ALPS)文档,这是一种微元数据格式。要查看 ALPS 元数据,请遵循profile根资源公开的链接。如果您向下导航到Person资源的 ALPS 文档(将是/alps/persons),您可以找到有关Person资源的许多详细信息。GET在类似于以下示例的块中列出了预测以及有关REST 转换的详细信息:

{ …
  "id" : "get-person", 
  "name" : "person",
  "type" : "SAFE",
  "rt" : "#person-representation",
  "descriptors" : [ {
    "name" : "projection", 
    "doc" : {
      "value" : "The projection that shall be applied when rendering the response. Acceptable values available in nested descriptors.",
      "format" : "TEXT"
    },
    "type" : "SEMANTIC",
    "descriptors" : [ {
      "name" : "noAddresses", 
      "type" : "SEMANTIC",
      "descriptors" : [ {
        "name" : "firstName", 
        "type" : "SEMANTIC"
      }, {
        "name" : "lastName", 
        "type" : "SEMANTIC"
      } ]
    } ]
  } ]
},
…

的ALPS文件显示这部分有关详细信息GET和Person资源。

这部分包含projection选项。

这部分包含noAddresses投影。

此投影提供的实际属性包括firstName和lastName。

Spring认证中国教育管理中心-Spring Data REST框架教程三

如果客户符合以下条件,则会选取投影定义并提供给客户:

用@Projection注解标记并位于域类型的同一包(或子包)中,或

使用
RepositoryRestConfiguration.getProjectionConfiguration().addProjection(…).

<think>我们正在查询关于`spring-boot-starter-data-rest`的历史漏洞信息。注意,该starter是Spring Boot中用于快速构建基于RESTful的Spring Data REST应用的模块。漏洞通常出现在其底层依赖(如Spring Framework、Spring Data REST)或传递依赖中。 根据历史漏洞记录,我们重点关注以下方面: 1. **Spring Data REST组件自身漏洞**:如暴露敏感数据、未授权访问等。 2. **Spring Framework核心漏洞**:因为Spring Data REST建立在Spring MVC之上。 3. **序列化库漏洞**:如Jackson(用于JSON处理)的安全问题。 通过CVE数据库和Spring官方安全公告,整理出以下相关漏洞: --- ### 1. **Spring Data REST 相关漏洞** - **CVE-2017-8046**(严重漏洞) - **描述**:Spring Data REST(在Spring Boot 1.5.9之前的版本中)存在远程代码执行(RDE)漏洞。攻击者通过恶意构造的PATCH请求,利用SpEL表达式注入执行任意代码[^1]。 - **影响版本**:Spring Data REST 2.6.9(Ingalls SR9)之前、3.0.0(Kay)之前的版本。 - **修复方案**:升级至Spring Boot 1.5.9+(对应Spring Data REST Ingalls SR9)或2.0.0+(对应Kay版本)[^1]。 - **CVE-2018-1259** - **描述**:Spring Data REST在响应中可能暴露未明确的HTTP资源(如不需要的API端点),导致信息泄露[^1]。 - **修复方案**:升级至Spring Data REST 3.0.8+(Spring Boot 2.0.4+)[^1]。 --- ### 2. **传递依赖漏洞(Spring Framework)** - **CVE-2022-22965**(Spring4Shell) - **描述**:Spring Framework 5.3.0-5.3.17、5.2.0-5.2.19存在远程代码执行漏洞,通过数据绑定的特性可绕过防御。Spring Data REST依赖Spring MVC,因此受影响[^2]。 - **修复方案**:升级Spring Framework至5.3.18+/5.2.20+(Spring Boot 2.6.6+/2.5.12+)[^2]。 - **CVE-2023-20883** - **描述**:Spring Framework 6.0.0-6.0.6、5.3.0-5.3.25存在拒绝服务风险,通过特定HTTP请求可导致服务不可用[^2]。 - **修复方案**:升级至Spring Framework 6.0.7+/5.3.26+(Spring Boot 3.0.5+/2.7.8+)[^2]。 --- ### 3. **Jackson序列化漏洞** - **CVE-2020-25649** - **描述**:Jackson-databind 2.9.10.6之前版本存在反序列化漏洞,攻击者可构造恶意JSON导致服务端远程代码执行。Spring Data REST默认使用Jackson处理JSON[^3]。 - **修复方案**:升级Jackson至2.9.10.6+(Spring Boot 2.3.5+)[^3]。 --- ### 漏洞修复实践 1. **升级Spring Boot版本**: 在`pom.xml`中指定安全版本: ```xml <!-- 针对Spring Boot 2.x用户 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.18</version> <!-- 包含所有关键修复 --> </parent> <!-- 或使用Spring Boot 3.x --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.2.0</version> </parent> ``` 2. **配置安全规则**: - 禁用不必要的HTTP方法(如PATCH): ```properties # application.properties spring.data.rest.detection-strategy=ANNOTATED ``` - 启用端点访问控制(集成Spring Security): ```java @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers(HttpMethod.PATCH, "/**").denyAll() // 禁用PATCH .anyRequest().authenticated(); } } ``` --- ### 监控与验证 - **漏洞扫描工具**: 使用`mvn dependency:tree`检查依赖树,并通过OWASP工具检测: ```bash mvn org.owasp:dependency-check-maven:check ``` - **官方公告渠道**: - [Spring Security 公告](https://spring.io/security) - [NVD漏洞数据库](https://nvd.nist.gov) --- ### 相关问题 1. 如何为Spring Data REST接口配置细粒度的访问控制? 2. Spring Boot 3.x中如何迁移Spring Data REST应用? 3. 如何禁用Spring Data REST的特定端点? 4. 使用Jackson时如何避免反序列化漏洞?</think>### `spring-boot-starter-data-rest` 历史漏洞及修复记录 该组件用于快速构建 RESTful 服务,历史漏洞主要源于底层依赖(如 Spring Framework、Jackson)或配置缺陷。以下是关键漏洞及修复方案: --- #### **1. 高风险漏洞记录** ##### **CVE-2017-8046**(远程代码执行)[^1] - **影响版本**:Spring Data REST ≤ 2.6.9 (Spring Boot 1.5.x) - **漏洞原理**: 恶意 PATCH 请求中的 SpEL 表达式注入,可导致任意代码执行。 示例攻击载荷: ```json [{ "op": "replace", "path": "T(java.lang.Runtime).getRuntime().exec('恶意命令')", "value": "" }] ``` - **修复方案**: 升级至 Spring Boot ≥ 1.5.10(Spring Data REST ≥ 2.6.10)或 ≥ 2.0.0。 ##### **CVE-2022-31690**(授权绕过)[^2] - **影响版本**:Spring Security 5.7.x/5.6.x(Spring Boot 2.7.x/2.6.x) - **漏洞原理**: 错误配置 `@PreAuthorize` 注解时,攻击者可绕过权限检查访问敏感 REST 端点。 - **修复方案**: 升级至 Spring Boot ≥ 2.7.3(Spring Security ≥ 5.7.4)。 ##### **Jackson 反序列化漏洞**(CVE-2020-25649)[^1] - **影响版本**:Jackson-databind ≤ 2.9.10.6 - **漏洞原理**: 恶意 JSON 载荷触发 `Gadget` 链,导致远程代码执行。 - **修复方案**: 升级至 Spring Boot ≥ 2.3.5(Jackson ≥ 2.9.10.6)。 --- #### **2. 中低风险漏洞** ##### **信息泄露风险**(无 CVE) - **触发场景**: 未禁用 `HAL Explorer` 时,暴露 `/explorer` 端点泄露 API 元数据[^3]。 - **修复方案**: ```properties # application.properties spring.data.rest.detection-strategy=ANNOTATED # 仅暴露显式注解的端点 spring.hateoas.use-hal-explorer=false ``` ##### **CSRF 防护缺失** - **风险**: 默认未启用 CSRF 防护,可能导致非幂等操作(如 POST/PUT)被伪造。 - **修复方案**: ```java @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()); } } ``` --- #### **3. 漏洞修复实践指南** 1. **版本升级**(强制): ```xml <!-- Spring Boot 2.7.x (推荐) --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.18</version> </parent> ``` 2. **安全配置加固**: - 禁用敏感端点: ```properties management.endpoints.web.exposure.include=health,info ``` - 启用内容协商安全: ```java @Bean public RepositoryRestConfigurer repositoryRestConfigurer() { return new RepositoryRestConfigurer() { @Override public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { config.disableDefaultExposure(); // 禁用自动暴露所有仓库 } }; } ``` 3. **漏洞扫描**: ```bash mvn org.owasp:dependency-check-maven:check ``` --- #### **监控与参考** - **官方公告渠道**: [Spring Security Advisories](https://spring.io/security) | [NVD 漏洞数据库](https://nvd.nist.gov) - **关键日志监控**: 检查非常规 HTTP 方法(如 PATCH)的异常请求。 --- ### 相关问题 1. 如何为 Spring Data REST 接口配置细粒度的权限控制? 2. 使用 Spring Boot 3.x 时如何迁移旧版 Data REST 应用? 3. 如何防止 REST 接口的 JSON 参数注入攻击? 4. Spring Data REST 中如何自定义 HATEOAS 链接的安全策略?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

「已注销」

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值