public interface Filter
FilterChain
.
On receipt of a request a filter implementation may either:
Promise
with
a QueryResponse
or a ResourceException
methods and returning
handlerXXX
method on the passed in request handler. Implementations are permitted to
modify the context or request before forwarding. They may also chain the
promise, returned from the downstream handler, in order to be notified when
a response is returned, allowing a filter to interact with responses before
they are sent to the client.
Implementations are allowed to invoke arbitrary handleXXX
methods on
the request handler if needed before deciding to stop or continue processing.
However, implementations should take care to ensure that the passed in result
handler is invoked at most once per request. This is useful in the case where
a filter implements some functionality as a composite of other operations
(e.g. theoretically, a password modify action could be intercepted within a
filter and converted into a read + update).
Filter chains are fully asynchronous: filters and request handlers may delegate work to separate threads either directly (i.e. new Thread() ...) or indirectly (e.g. via NIO completion handlers).
The following example illustrates how an authorization filter could be implemented:
public class AuthzFilter implements Filter { public Promise<Resource, ResourceException> filterRead(final Context context, final ReadRequest request, final RequestHandler next) { /* * Only forward the request if the request is allowed. */ if (isAuthorized(context, request)) { /* * Continue processing the request since it is allowed. Chain the * promise so that we can filter the returned resource. */ return next.handleRead(context, request) .thenAsync(new AsyncFunction<Resource, Resource, ResourceException>() { @Override public Promise<Resource, ResourceException> apply(Resource result) { /* * Filter the resource and its attributes. */ if (isAuthorized(context, result)) { return Promises.newResultPromise(filterResource(context, result)); } else { return newExceptionPromise(ResourceException.newNotFoundException()); } } }, new AsyncFunction<ResourceException, Resource, ResourceException>() { @Override public Promise<Resource, ResourceException> apply(ResourceException error) { // Forward - assumes no authorization is required. return newExceptionPromise(error); } }); } else { /* * Stop processing the request since it is not allowed. */ ResourceException exception = new ForbiddenException(); return newExceptionPromise(exception); } } // Remaining filterXXX methods... }
Filters
Promise<ActionResponse,ResourceException> filterAction(Context context, ActionRequest request, RequestHandler next)
context
- The filter chain context.request
- The action request.next
- A request handler representing the remainder of the filter
chain.Promise
containing the result of the operation.Promise<ResourceResponse,ResourceException> filterCreate(Context context, CreateRequest request, RequestHandler next)
context
- The filter chain context.request
- The create request.next
- A request handler representing the remainder of the filter
chain.Promise
containing the result of the operation.Promise<ResourceResponse,ResourceException> filterDelete(Context context, DeleteRequest request, RequestHandler next)
context
- The filter chain context.request
- The delete request.next
- A request handler representing the remainder of the filter
chain.Promise
containing the result of the operation.Promise<ResourceResponse,ResourceException> filterPatch(Context context, PatchRequest request, RequestHandler next)
context
- The filter chain context.request
- The patch request.next
- A request handler representing the remainder of the filter
chain.Promise
containing the result of the operation.Promise<QueryResponse,ResourceException> filterQuery(Context context, QueryRequest request, QueryResourceHandler handler, RequestHandler next)
Implementations which return results directly rather than forwarding the
request should invoke QueryResourceHandler.handleResource(ResourceResponse)
for each resource which matches the query criteria. Once all matching
resources have been returned implementations are required to return
either a QueryResponse
if the query has completed successfully, or
ResourceException
if the query did not complete successfully
(even if some matching resources were returned).
context
- The filter chain context.request
- The query request.handler
- The resource handler.next
- A request handler representing the remainder of the filter
chain.Promise
containing the result of the operation.Promise<ResourceResponse,ResourceException> filterRead(Context context, ReadRequest request, RequestHandler next)
context
- The filter chain context.request
- The read request.next
- A request handler representing the remainder of the filter
chain.Promise
containing the result of the operation.Promise<ResourceResponse,ResourceException> filterUpdate(Context context, UpdateRequest request, RequestHandler next)
context
- The filter chain context.request
- The update request.next
- A request handler representing the remainder of the filter
chain.Promise
containing the result of the operation.Copyright © 2010-2020, ForgeRock All Rights Reserved.