|
26 | 26 | /**
|
27 | 27 | * Registry for defining Access Control Lists (ACLs) programmatically.
|
28 | 28 | *
|
29 |
| - * This registry is utilized by the {@code ACLRegistryVetoer} and {@code ACLRegistryAllower} authorizers |
30 |
| - * to manage request permissions. The {@code ACLRegistryVetoer} denies requests based on veto predicates, |
31 |
| - * while the {@code ACLRegistryAllower} grants permission to proceed with requests based on allow predicate. |
| 29 | + * <p>This registry serves as a central repository for dynamic access control rules that can be |
| 30 | + * registered at runtime. It is utilized by the {@code ACLRegistryVetoer} and {@code ACLRegistryAllower} |
| 31 | + * authorizers to manage request permissions in a flexible, programmatic manner.</p> |
32 | 32 | *
|
33 |
| - * A request is permitted to proceed if it is not denied by any {@code ACLRegistryVetoer} and at least one |
34 |
| - * {@code ACLRegistryAllower} approves it. |
| 33 | + * <h2>Authorization Model</h2> |
| 34 | + * <p>The registry implements a two-phase authorization model:</p> |
| 35 | + * <ol> |
| 36 | + * <li><strong>Veto Phase:</strong> The {@code ACLRegistryVetoer} evaluates all registered veto |
| 37 | + * predicates. If any predicate returns {@code true}, the request is immediately denied.</li> |
| 38 | + * <li><strong>Allow Phase:</strong> If not vetoed, the {@code ACLRegistryAllower} checks if at |
| 39 | + * least one allow predicate returns {@code true}. The request proceeds only if approved.</li> |
| 40 | + * </ol> |
35 | 41 | *
|
36 |
| - * Example usage: |
37 |
| - * <pre> |
38 |
| - * {@code |
| 42 | + * <p>A request is permitted to proceed if and only if:</p> |
| 43 | + * <ul> |
| 44 | + * <li>It is not denied by any {@code ACLRegistryVetoer} predicates, AND</li> |
| 45 | + * <li>At least one {@code ACLRegistryAllower} predicate approves it</li> |
| 46 | + * </ul> |
| 47 | + * |
| 48 | + * <h2>Example Usage</h2> |
| 49 | + * <pre>{@code |
39 | 50 | * @Inject("acl-registry")
|
40 | 51 | * ACLRegistry registry;
|
41 | 52 | *
|
42 | 53 | * @OnInit
|
43 | 54 | * public void init() {
|
44 |
| - * registry.registerVeto(request -> request.getPath().equals("/deny")); |
45 |
| - * registry.registerAllow(request -> request.getPath().equals("/allow")); |
46 |
| - * } |
| 55 | + * // Deny all requests to /admin from non-admin users |
| 56 | + * registry.registerVeto(request -> |
| 57 | + * request.getPath().startsWith("/admin") && |
| 58 | + * !request.isAccountInRole("admin") |
| 59 | + * ); |
| 60 | + * |
| 61 | + * // Allow authenticated users to access /api |
| 62 | + * registry.registerAllow(request -> |
| 63 | + * request.getPath().startsWith("/api") && |
| 64 | + * request.isAuthenticated() |
| 65 | + * ); |
| 66 | + * |
| 67 | + * // Require authentication for all /secure paths |
| 68 | + * registry.registerAuthenticationRequirement(request -> |
| 69 | + * request.getPath().startsWith("/secure") |
| 70 | + * ); |
47 | 71 | * }
|
48 |
| - * </pre> |
| 72 | + * }</pre> |
49 | 73 | *
|
50 | 74 | * @author Andrea Di Cesare {@literal <andrea@softinstigate.com>}
|
| 75 | + * @since 6.0.0 |
| 76 | + * @see org.restheart.security.plugins.authorizers.ACLRegistryVetoer |
| 77 | + * @see org.restheart.security.plugins.authorizers.ACLRegistryAllower |
51 | 78 | */
|
52 | 79 | public interface ACLRegistry {
|
53 | 80 | /**
|
54 | 81 | * Registers a veto predicate that determines if a request should be denied.
|
55 |
| - * When the predicate evaluates to true, the request is immediately forbidden (vetoed). |
56 |
| - * Additionally, a request will also be denied if it is not explicitly authorized by any |
57 |
| - * allow predicates or any other active allowing authorizers. |
| 82 | + * |
| 83 | + * <p>When the predicate evaluates to {@code true}, the request is immediately forbidden (vetoed) |
| 84 | + * with no further evaluation. This provides a mechanism for implementing hard denials that cannot |
| 85 | + * be overridden by allow rules.</p> |
| 86 | + * |
| 87 | + * <p>Common use cases for veto predicates include:</p> |
| 88 | + * <ul> |
| 89 | + * <li>Blocking access to sensitive administrative endpoints</li> |
| 90 | + * <li>Enforcing IP-based access restrictions</li> |
| 91 | + * <li>Preventing access during maintenance windows</li> |
| 92 | + * <li>Implementing rate limiting or abuse prevention</li> |
| 93 | + * </ul> |
| 94 | + * |
| 95 | + * <p><strong>Note:</strong> Veto predicates are evaluated before allow predicates. A single |
| 96 | + * veto is sufficient to deny a request, regardless of any allow rules.</p> |
58 | 97 | *
|
59 |
| - * @param veto The veto predicate to register. This predicate should return true to veto (deny) the request, |
60 |
| - * and false to let the decision be further evaluated by allow predicates or other authorizers. |
| 98 | + * @param veto The veto predicate to register. This predicate should return {@code true} to veto |
| 99 | + * (deny) the request, and {@code false} to let the decision be further evaluated |
| 100 | + * by allow predicates or other authorizers |
| 101 | + * @throws NullPointerException if the veto predicate is null |
61 | 102 | */
|
62 | 103 | public void registerVeto(Predicate<Request<?>> veto);
|
63 | 104 |
|
64 | 105 | /**
|
65 | 106 | * Registers an allow predicate that determines if a request should be authorized.
|
66 |
| - * The request is authorized if this predicate evaluates to true, provided that no veto predicates |
67 |
| - * or other active vetoer authorizers subsequently deny the request. This method helps in setting up |
68 |
| - * conditions under which requests can proceed unless explicitly vetoed. |
| 107 | + * |
| 108 | + * <p>The request is authorized if this predicate evaluates to {@code true}, provided that no |
| 109 | + * veto predicates or other active vetoer authorizers have denied the request. Multiple allow |
| 110 | + * predicates can be registered, and the request proceeds if any one of them returns {@code true}.</p> |
| 111 | + * |
| 112 | + * <p>Common use cases for allow predicates include:</p> |
| 113 | + * <ul> |
| 114 | + * <li>Granting access based on user roles or permissions</li> |
| 115 | + * <li>Implementing path-based access control</li> |
| 116 | + * <li>Allowing access based on request headers or parameters</li> |
| 117 | + * <li>Implementing custom business logic for authorization</li> |
| 118 | + * </ul> |
| 119 | + * |
| 120 | + * <p><strong>Important:</strong> Allow predicates are only evaluated if no veto predicates |
| 121 | + * have denied the request. At least one allow predicate must return {@code true} for the |
| 122 | + * request to be authorized.</p> |
69 | 123 | *
|
70 |
| - * @param allow The allow predicate to register. This predicate should return true to authorize the request, |
71 |
| - * unless it is vetoed by any veto predicates or other vetoing conditions. |
| 124 | + * @param allow The allow predicate to register. This predicate should return {@code true} to |
| 125 | + * authorize the request, unless it is vetoed by any veto predicates or other |
| 126 | + * vetoing conditions |
| 127 | + * @throws NullPointerException if the allow predicate is null |
72 | 128 | */
|
73 | 129 | public void registerAllow(Predicate<Request<?>> allow);
|
74 | 130 |
|
75 | 131 | /**
|
76 |
| - * Registers a predicate that determines whether requests handled by the ACLRegistryAllower |
77 |
| - * require authentication. This method is used to specify conditions under which authentication |
78 |
| - * is mandatory. Typically, authentication is required unless there are allow predicates |
79 |
| - * explicitly authorizing requests that are not authenticated. |
80 |
| - * |
| 132 | + * Registers a predicate that determines whether requests require authentication. |
| 133 | + * |
| 134 | + * <p>This method is used to specify conditions under which authentication is mandatory before |
| 135 | + * authorization rules are evaluated. When the predicate returns {@code true}, the request must |
| 136 | + * have valid authentication credentials; otherwise, it will be rejected with a 401 Unauthorized |
| 137 | + * status.</p> |
| 138 | + * |
| 139 | + * <p>Authentication requirements are evaluated before authorization rules. This ensures that |
| 140 | + * sensitive endpoints can enforce authentication regardless of allow predicates.</p> |
| 141 | + * |
| 142 | + * <p>Common use cases include:</p> |
| 143 | + * <ul> |
| 144 | + * <li>Requiring authentication for all API endpoints</li> |
| 145 | + * <li>Enforcing authentication for specific URL patterns</li> |
| 146 | + * <li>Making authentication mandatory for certain HTTP methods</li> |
| 147 | + * <li>Implementing mixed authentication models (some paths public, others protected)</li> |
| 148 | + * </ul> |
| 149 | + * |
| 150 | + * <p>Example:</p> |
| 151 | + * <pre>{@code |
| 152 | + * // Require authentication for all paths except /public |
| 153 | + * registry.registerAuthenticationRequirement(request -> |
| 154 | + * !request.getPath().startsWith("/public") |
| 155 | + * ); |
| 156 | + * }</pre> |
81 | 157 | *
|
82 | 158 | * @param authenticationRequired The predicate to determine if authentication is necessary.
|
83 |
| - * It should return true if the request must be authenticated, |
84 |
| - * otherwise false if unauthenticated requests might be allowed. |
| 159 | + * It should return {@code true} if the request must be authenticated, |
| 160 | + * otherwise {@code false} if unauthenticated requests might be allowed |
| 161 | + * @throws NullPointerException if the authenticationRequired predicate is null |
85 | 162 | */
|
86 | 163 | public void registerAuthenticationRequirement(Predicate<Request<?>> authenticationRequired);
|
87 | 164 |
|
|
0 commit comments