我有一个带有GET动词端点的REST处理程序。从标识符(MongoDB的ObjectID)中获取该实体的信息。
验证ObjectID是否有效并避免使用Spring Data Mongo时出错。我按照JPA bean验证标准的指导开发了一个简单的验证器。
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Constraint(validatedBy = ValidObjectIdValidator.class)
@NotNull
@Documented
public @interface ValidObjectId {
String message() default "{constraints.valid.objectid}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
public class ValidObjectIdValidator implements ConstraintValidator<ValidObjectId, String> {
@Override
public void initialize(ValidObjectId constraintAnnotation) {}
@Override
public boolean isValid(String id, ConstraintValidatorContext context) {
return ObjectId.isValid(id);
}
}
然后我使用以下配置应用控制器的可变级验证:
@Api
@RestController("RestUserController")
@Validated
@RequestMapping("/api/v1/children/")
public class ChildrenController implements ISonHAL, ICommentHAL, ISocialMediaHAL
在控制器级别使用 @Validated 注释。
@GetMapping(path = "/{id}")
@ApiOperation(value = "GET_SON_BY_ID", nickname = "GET_SON_BY_ID", notes = "Get Son By Id",
response = SonDTO.class)
@PreAuthorize("@authorizationService.hasParentRole() && @authorizationService.isYourSon(#id)")
public ResponseEntity<APIResponse<SonDTO>> getSonById(
@Valid @ValidObjectId(message = "{son.id.notvalid}")
@ApiParam(value = "id", required = true) @PathVariable String id) throws Throwable {
logger.debug("Get User with id: " + id);
return Optional.ofNullable(sonService.getSonById(id))
.map(sonResource -> addLinksToSon(sonResource))
.map(sonResource -> ApiHelper.<SonDTO>createAndSendResponse(ChildrenResponseCode.SINGLE_USER, HttpStatus.OK, sonResource))
.orElseThrow(() -> { throw new SonNotFoundException(); });
}
在@PathVariable上使用 @Valid注释。
问题是我必须验证用户当前是否经过身份验证是他想要查看其信息的孩子的父母。执行以下内容验证了这一点:
@PreAuthorize("@authorizationService.hasParentRole() && @authorizationService.isYourSon(#id)")
这里发生了错误。因为我必须将收到的ID转换为ObjectID mediate new ObjectId (id)
。这可能无效。
有没有办法在授权之前配置验证?
这是我在方法级别启用安全性的配置:
@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
提前致谢。