-
Notifications
You must be signed in to change notification settings - Fork 39
Validation of resources
@available since 1.10.0
Sometimes the schema validation for resources is not enough and you need to do some extra validations on the resources for eg. mutually exclusive fields. Such a validation cannot be expressed in a schema definition and therefore it is now possible to add custom RequestValidation
implementations adding error messages to it that will then be returned in a standardized way within the SCIM ErrorResponse
. Please note that the extensions I added here to the SCIM ErrorResponse
are not part of the SCIM specification but it also does not break the specification.
You can add a RequestValidator
implementation to your ResourceHandler
implementation by overriding the method getRequestValidator
/**
* @return allows to define a custom request validator that is executed after schema validation and before the
* call to the actual {@link ResourceHandler} implementation.
*/
public RequestValidator<T> getRequestValidator()
{
return userRequestValidator
}
this request validator will be used in POST
, PUT
and PATCH
requests and allows you to do extra validations directly after the resource has been validated against its schema.
If errors occurred during schema validation you will get them passed through into your implementation of RequestValidator
with the ValidationContext
object. This object collects all violations found during schema validation and will add them to the ValidationContext
object. Any error found will be added into the SCIM error response. If no error is directly specified a randomized message from the ValidationContext
will be put into the detail
-attribute of the ErrorResponse
.
An error that occurred during schema validation and is mappable onto a specific resource field will be added into the response body under the fields name. Nested field-names will be separated by a dot .
e.g. name.givenName
, see example below:
{
"detail" : "Request document is invalid it does not contain processable data",
"schemas" : [ "urn:ietf:params:scim:api:messages:2.0:Error" ],
"status" : 400,
"errors" : {
"errorMessages" : [ "Request document is invalid it does not contain processable data" ],
"fieldErrors" : {
"displayName" : [ "The 'STRING'-attribute 'urn:ietf:params:scim:schemas:core:2.0:User:displayName' with value 'abc' must have a minimum length of '5' characters but is '3' characters long" ],
"userName" : [ "Required 'READ_WRITE' attribute 'urn:ietf:params:scim:schemas:core:2.0:User:userName' is missing" ]
}
}
}
Within your custom implementation you can extend the ValidationContext
up to your hearts will but be careful to add only error messages directly to field names that are defined within the schemas definition of the resource otherwise an InternalServerException
might be thrown during runtime.
If you define an extension that uses attributes with names that collide with the main-schema of the defined resource-type you will have no direct way in determining to which schema the error message belongs. A better practice would be to make sure that you do not have any shared names within resources and extensions.
The ValidationContext
allows you to set the http response status based on the type on error that you determined during validation e.g. 409 (CONFLICT) due to unique attribute collision.
It is also possible to add additional HTTP headers. In very rare cases an error might trigger a special usecase that demands a HTTP redirect to another service after an error. If this is the case you may do this by setting the response status and the headers with the ValidationContext
Do not throw exceptions within your custom RequestValidator
implementation. Simply add new errors to the ValidationContext
. This object is evaluated afterwards and will be parsed into an appropriate ErrorResponse
if any errors have been found.