The API Validator filter validates all requests against a configured Web Application Description Language (WADL) file. For example, if a request to the origin service is missing the tenant ID in the URI, but the origin service requires the tenant ID to be there, then the request will be rejected before it reaches the origin service. The API Validator filter can also be configured to validate the content of the request body against an XML Schema Definition (XSD) or JSON Schema referenced as a grammar in the WADL.

A working knowledge of WADL’s and XSD’s/JSON Schemas will make the configuration of this filter much easier. Therefore, it is recommended that you read up on these subjects before attempting to use this filter. A good tutorial on XSD 1.1, including a comparison of XSD 1.1 and XSD 1.0, is located at:

Most of the ideas described in this conference session are implemented in this filter:

General filter information

  • Name: api-validator

  • Default Configuration: validator.cfg.xml

  • Released: v2.1.6

  • Bundle: repose-extensions-filter-bundle

  • Schema

Prerequisites & Postconditions

Required Request Headers

This filter does not require any request headers.

However, the configuration can require specific headers and/or values be present in order to successfully exit this filter. The most common use of a request header by this filter is for Role-Based Access Control (RBAC) using the X-Roles, X-Tenant-Id, and/or X-Map-Roles headers populated by either the Keystone v2 filter or the Keystone v2 Authorization filter.

Required Preceding Filters

This filter has no dependencies on other filters and can be placed wherever it is needed in the filter chain.

However, due to the nature of this filter it is typically placed early in the filter chain immediately after any authentication filters.

Request Headers Created

  • X-Relevant-Roles - Lists the values of the X-Roles header which match a rax:roles value from the WADL for the resource being requested. In other words, X-Relevant-Roles are the user roles which granted access to the resource. This header is only added to the request if enable-rax-roles is configured to be true.

  • X-Delegated - Provides details about the failure being delegated by this filter. This is mainly intended for use by the Highly Efficient Record Processor (HERP) filter and Delegation Response Processor (DeRP) filter for internal delegation processing within Repose. However, it can be exposed to the origin service under certain configurations. This header is only added if delegation is enabled.

Request Body Changes

This filter does not modify the request body.

This filter is not strictly required by any other filters.

Response Body Changes

This filter does not modify the response body.

Response Headers Created

This filter does not create/modify any response headers.

Response Status Codes

Table 1. Status Codes
Status Code Reasons

400

The body of a request fails to validate.

401

A requested resource or method requires a specific X-Authenticated-By request header value that was not found.

403

A requested resource or method requires a specific X-Roles request header value that was not found.

404

The filter determined that the URI is invalid.

When mask-rax-roles-403 attribute is enabled (i.e., true), this could also indicate the supplied X-Roles request header value did not have access to the URI.

405

The URI is valid, but the Method is not appropriate for the URI.

When mask-rax-roles-403 attribute is enabled (i.e., true), this could also indicate the supplied X-Roles request header value had access to the URI, but not the requested Method.

Through the use of the rax:code WADL extension, any of these default codes can be overridden to any value.

Examples

Basic Example

This configuration is the most basic example of this filter’s configuration.

validator.cfg.xml
<validators xmlns="http://docs.openrepose.org/repose/validator/v1.0">
    <validator role="default" (1)
               default="true" (2)
               wadl="file:///path/to/wadl/file.wadl" (3)
    />
</validators>
1 The role attribute is deprecated, but is currently required and doesn’t have a default value.
2 The default attribute is deprecated.
Default: false
3 This is the fully qualified URI for where the WADL file can be located.

Even though multiple validator element definitions and the role and default attributes on each are deprecated, the easiest way to future proof new configurations is to:

  • define a single validator as this will eventually become the root element

  • define that validator element with:

    • a role attribute with the value of default

    • a default attribute with the value of true

All the features of a validator element

This configuration expands the basic example in order to show off all of the features of this element.

validator.cfg.xml
<validators xmlns="http://docs.openrepose.org/repose/validator/v1.0">
    <validator role="default" (1)
               default="true" (2)
               wadl="file:///path/to/wadl/file.wadl" (3)
               enable-api-coverage="false" (4)
               dot-output="/tmp/default.dot" (5)
               check-well-formed="false" (6)
               check-grammars="false" (7)
               check-elements="true" (8)
               check-plain-params="true" (9)
               do-xsd-grammar-transform="true" (10)
               enable-pre-process-extension="true" (11)
               remove-dups="true" (12)
               xpath-version="2" (13)
               xsl-engine="XalanC" (14)
               xsd-engine="Xerces" (15)
               enable-ignore-xsd-extension="false" (16)
               join-xpath-checks="false" (17)
               validator-name="testName" (18)
               check-headers="true" (19)
               enable-rax-roles="false" (20)
               mask-rax-roles-403="false" (21)
               validate-checker="true" (22)
    />
</validators>
1 List of roles from which at least one role must match a role in the request for this validator to be applied. Triggers off of X-Roles header.
DEPRECATED: Roles defined outside of the WADL will not be supported in Repose 9 and this attribute will not be available.
2 If the api-validator config multi-match is set to true then the default validator will be the first validator to process the incoming request. If multi-match is set to false and if no validator is matched to the users' roles, then the filter will use the default validator.
Default: false
DEPRECATED: Multiple validators will not be supported in Repose 9 and this attribute will not be available.
3 Location of the WADL to associate with this validator. If not specified, then the wadl needs to be embedded within the validator element. Can be located within the file system or pointed to a remote file. Can use absolute or relative path.
DEPRECATED: This attribute is currently optional, but will be required in Repose 9. Currently both a WADL file and embedded WADL can not be defined. Currently at least a WADL file or embedded WADL must be defined.
4 If set to true, this validator will record, via JMX, the number of times each state in the generated state machine (the mechanism underlying api validation) is accessed. These values may be used to determine api usage and coverage.
Default: false
5 The DOT output file for this validator. DOT is a plain text graph description language that is a simple way of describing graphs that both humans and applications can use.
6 Check that the request body is well-formed XML or JSON that conforms to the XML or JSON syntax rules.
Default: false
7 If set to true and the WADL references an XSD or JSON grammar(s), then the incoming request body will be validated against the grammar(s).
Default: false
8 If set to true and the WADL request representation contains an element the filter will check the root element of a request.
Default: false
9 If set to true and the WADL has plain parameters defined, then the filter will check the plain parameters.
Default: false
10 Allow XSD grammar transform. Transform the XML after validation, to fill in things like default values.
Default: false
11 If set to true allows the filter to perform a transform before xsd validation takes place. The transformation rules can be defined in the WADL via the Rackspace WADL extension: rax:preprocess
Default: true
12 Analyzes the state machine generated from the WADL and makes sure that there aren’t any duplicate nodes in the machine.
Default: true
13 XPath version used in the WADL. Can be 1 or 2.
Default: 1
NOTE: IF 1 is set, THEN the Xalan implementation will be used; ELSE IF 2, THEN Saxon will be used.
NOTE: XPath 2 with schema awareness requires a Saxon license.
14 Indicates the XSL engine to use from the possible list of:
° Xalan - Standard Java XSL engine
° XalanC - compiles XSL into byte code and is a very efficient 1.0 engine
° SaxonHE - Implements v2.0 of the XSL language, but gives a license error when attempting a transform.
° SaxonEE - Implements v2.0 of the XSL language, and allows transforms.
Default: XalanC
NOTE: Even though Saxon is an XSL 2.0 engine, most 1.0 XSLs should work fine.
15 Indicates the XSD engine to use for validation from the possible list of:
° Xerces
° SaxonEE
Default: Xerces
NOTE: The SaxonEE validator requires a license.
16 Enables the use of the rax:ignoreXSD extension in WADL files to exclude some representations from validation against the XSD.
Default: true
17 This is an optimization where the well formed check and multiple XPath checks can be merged into a single check.
Default: true
18 Sets the name for this validator. The name is used as the MBean name when connecting to Repose via JMX.
19 If set to true and the WADL defines required headers then the filter will check that those required headers are present.
Default: false
20 Enables use of the rax:roles extension in WADL files for determining resource access.
Default: false
NOTE: IF true, THEN rax:roles defined in the supplied WADL files will be used to determine resource access.
NOTE: IF true, THEN check-headers will also be enabled regardless of it’s setting.
21 Mask rax-roles with 404 and 405 errors. By default rax-roles responds with a 403 if there is a role mismatch. If this is set to true, then the response will be 404 if no methods are accessible or 405 if some methods are available.
Default: false
22 If set to true, then the validity of the generated state machine is checked (e.g., no dead-end paths, there is a single start state, no orphaned nodes, etc.).
Default: true

Enable Delegation

To place this filter in Delegation mode, add the delegating element to the filter configuration with an optional quality attribute that determines the delegating priority.

validator.cfg.xml
<validators xmlns="http://docs.openrepose.org/repose/validator/v1.0">
    <validator role="default"
               default="true"
               wadl="file:///path/to/wadl/file.wadl"
    />
    <delegating quality="0.3"/>  (1) (2)
</validators>
1 If this element is present, then delegation is enabled. Delegation will cause this filter to pass requests it would ordinarily reject along with a header detailing why it would have rejected the request.
2 Indicates the quality that will be added to any output headers. When setting up a chain of delegating filters the highest quality number will be the one that is eventually output.
Default: 0.3

Deprecated Multi-Validator Definition

This configuration shows the deprecated, but currently legal, multi-validator definition as well as an embedded WADL which is also deprecated.

validator.cfg.xml
<validators xmlns="http://docs.openrepose.org/repose/validator/v1.0">
    <validator role="default"
               default="true"
               wadl="file:///path/to/wadl/file.wadl"
    />
    <validator role="embedded" (1)
               default="false" (2)
               check-well-formed="false"
               check-grammars="true"
               check-elements="true"
               check-headers="true">
        <application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" (3)
                     xmlns:xs="http://www.w3.org/2001/XMLSchema"
                     xmlns:test="http://test.openrespose/test/v1.1"
                     xmlns="http://wadl.dev.java.net/2009/02"
                     xsi:schemaLocation="http://test.openrespose/test/v1.1 test.xsd">
            <grammars>
                <include href="test.xsd"/>
            </grammars>
            <resources base="http://localhost:8088/">
                <resource path="/wadl/group1">
                    <resource path="/resource1">
                        <resource path="{id}">
                            <param xmlns:xs="http://www.w3.org/2001/XMLSchema" type="xs:string" style="template"
                                   name="id"/>
                            <method name="PUT" id="putContainer">
                                <response>
                                    <representation mediaType="application/xml"/>
                                </response>
                            </method>
                            <method name="DELETE" id="deleteContainer"/>
                            <method name="GET" id="getContainer">
                                <request>
                                    <param xmlns:xs="http://www.w3.org/2001/XMLSchema" type="xs:string" style="query"
                                           name="search"/>
                                </request>
                                <response>
                                    <representation mediaType="application/xml"/>
                                </response>
                            </method>
                            <resource path="{item}">
                                <param xmlns:xs="http://www.w3.org/2001/XMLSchema" type="test:UUID" style="template"
                                       name="item"/>
                                <method name="PUT" id="putItem">
                                    <request>
                                        <representation mediaType="*/*"/>
                                    </request>
                                    <response>
                                        <representation mediaType="*/*"/>
                                    </response>
                                </method>
                                <method name="POST" id="postItem">
                                    <request>
                                        <representation mediaType="application/xml"/>
                                    </request>
                                    <response>
                                        <representation mediaType="*/*"/>
                                    </response>
                                </method>
                                <method name="DELETE" id="deleteItem"/>
                                <method name="GET" id="getItem">
                                    <response>
                                        <representation mediaType="*/*"/>
                                    </response>
                                </method>
                            </resource>
                        </resource>
                    </resource>
                </resource>
            </resources>
        </application>
    </validator>
</validators>
1 Defines the roles to which this validator is applied.
DEPRECATED: Roles defined outside of the WADL will not be supported in Repose 9 and this attribute will not be available.
2 Indicates that this is not the default validator.
DEPRECATED: Multiple validators will not be supported in Repose 9 and this attribute will not be available.
3 Shows how to embed a WADL into the configuration.
DEPRECATED: This element body is currently optional, but will not be supported in Repose 9. Currently both a WADL file and embedded WADL can not be defined. Currently at least a WADL file or embedded WADL must be defined.

Additional Information

This filter is based on the API Checker library.

Metrics

This component reports the following metrics to the Metrics Service:

Metric Type Metric Name Description

Meter

org.openrepose.filters.apivalidator.ApiValidatorHandler.invalid-request.<role>

Counts the number of times an invalid request with role <role> is rejected. <role> is a value pulled from the X-Roles header.

Meter

org.openrepose.filters.apivalidator.ApiValidatorHandler.invalid-request.ACROSS ALL

Counts the number of times an invalid request is rejected. This meter is the sum of all org.openrepose.filters.apivalidator.ApiValidatorHandler.invalid-request.<role> meters.