Last active
September 13, 2023 02:04
-
-
Save susimsek/03b6a4d695b864dfe95d1b31959b3e53 to your computer and use it in GitHub Desktop.
Spring Boot File Content Type Validation With Annotation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@ControllerAdvice | |
public class CustomExceptionControllerAdvice { | |
@ExceptionHandler(MultipartException.class) | |
void handleMultipartException(MultipartException ex,HttpServletResponse response) throws IOException { | |
response.sendError(HttpStatus.BAD_REQUEST.value(),"Please select a file"); | |
} | |
@ExceptionHandler(ConstraintViolationException.class) | |
public void handleConstraintViolationException(ConstraintViolationException ex,HttpServletResponse response) throws IOException { | |
response.sendError(HttpStatus.BAD_REQUEST.value()); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@RestController | |
@FieldDefaults(level = AccessLevel.PRIVATE,makeFinal=true) | |
@RequestMapping("/versions/1") | |
public class FileController { | |
@PostMapping("/files") | |
@ResponseStatus(HttpStatus.OK) | |
public String createFile(@Validated @ValidFile @RequestPart("file") MultipartFile file { | |
return file.getOriginalFilename() | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class FileValidator implements ConstraintValidator<ValidFile, MultipartFile> { | |
@Override | |
public void initialize(ValidFile constraintAnnotation) { | |
} | |
@Override | |
public boolean isValid(MultipartFile multipartFile, ConstraintValidatorContext context) { | |
boolean result = true; | |
String contentType = multipartFile.getContentType(); | |
if (!isSupportedContentType(contentType)) { | |
result = false; | |
} | |
return result; | |
} | |
private boolean isSupportedContentType(String contentType) { | |
return contentType.equals("text/xml") | |
|| contentType.equals("application/pdf") | |
|| contentType.equals("image/png") | |
|| contentType.equals("image/jpg") | |
|| contentType.equals("image/jpeg"); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Documented | |
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE}) | |
@Retention(RetentionPolicy.RUNTIME) | |
@Constraint(validatedBy = {FileValidator.class}) | |
public @interface ValidFile { | |
String message() default "Only PDF,XML,PNG or JPG images are allowed"; | |
Class<?>[] groups() default {}; | |
Class<? extends Payload>[] payload() default {}; | |
} |
For validation exceptions e.g. ConstraintViolationException
, I use another exception handler. You may have a look at validator package in the following repo:
This can still be bypassed because you're only relying on the headers, which can be spoofed. True content validation can only happen when you inspect the uploaded file (the temporary file) before accepting it and moving it to your destination
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I tried to do something similar to this! It is working great. I'm trying to return a message from constraint violation exception and it's returning me the message but it's returning the propertyPath of the violation as well.
RESPONSE: uploadCafeImage.file: Max allowed file size is 200KB only. Uploaded file size 675KB
EXPECTED: Max allowed file size is 200KB only. Uploaded file size 675KB
Can you suggest a way to get rid of this uploadCafeImage.file property path from the response?