{title:'Guards', updated:'9.0.0'}

Guards control access to REST classes and methods. When guards are associated at the class-level, it's equivalent to associating guards on all Java methods on the servlet. If multiple guards are present, ALL guards must pass. (Note that this is different in behavior to {@doc jrs.Matchers Matchers} which require only one matcher to pass.)

Guards are associated with resource classes and methods via the following:

- {@link oajr.annotation.Rest}
  - {@link oajr.annotation.Rest#guards() guards}
- {@link oajr.annotation.RestOp}
  - {@link oajr.annotation.RestOp#guards() guards}

##### Example:

| // Define a guard that only lets Billy make a request | public BillyGuard extends RestGuard { | | @Override /* RestGuard */ | public boolean isRequestAllowed(RestRequest req) { | return req.getUserPrincipal().getName().equals("Billy"); | } | } | | // Servlet with class-level guard applied | @Rest(guards=BillyGuard.class) | public MyRestServlet extends BasicRestServlet implements BasicUniversalConfig { | | // Delete method that only Billy is allowed to call. | @RestDelete | public doDelete(RestRequest req, RestResponse res) throws Exception {...} | }

A common use for guards is to only allow admin access to certain Java methods...

| // DELETE method | @RestDelete(guards={AdminGuard.class}) | public void doDelete(RestRequest req, RestResponse res) throws Exception {...}

| public class AdminGuard extends RestGuard { | | @Override /* RestGuard */ | public boolean isRequestAllowed(RestRequest req) { | return req.getUserPrincipal().isUserInRole("ADMIN"); | } | }

A guard failure results in an HTTP 401 Unauthorized response. However, this can be configured by overriding {@link oajr.guard.RestGuard#guard(RestRequest,RestResponse)} and processing the response yourself.

| public class AdminGuard extends RestGuard { | | @Override /* RestGuard */ | public boolean guard(RestRequest req, RestResponse res) throws BasicHttpException { | if (! isOkay(req)) | throw new Forbidden("Access denied!!!"); | return true; | } | }

A simplified format is available for matching based on the user role on the request using the following:

- {@link oajr.annotation.Rest}
  - {@link oajr.annotation.Rest#roleGuard() roleGuard}
- {@link oajr.annotation.RestOp}
  - {@link oajr.annotation.RestOp#roleGuard() roleGuard}

##### Example:

| @Rest( | path="/foo", | roleGuard="ROLE_ADMIN || (ROLE_READ_WRITE && ROLE_SPECIAL)" | ) | public class MyResource extends BasicRestServlet implements BasicUniversalConfig { | ... | }