0
# Security Annotations
1
2
Jakarta Security Annotations provide declarative authorization and role-based access control for methods and classes. These annotations enable fine-grained security without programmatic security checks, allowing developers to express security constraints directly in the code.
3
4
## Capabilities
5
6
### Role-Based Access Control
7
8
Annotations for specifying which security roles can access methods and classes.
9
10
#### @RolesAllowed
11
12
Specifies the list of security roles permitted to access method(s) or class. Method-level annotations override class-level annotations when they conflict.
13
14
```java { .api }
15
/**
16
* Specifies security roles permitted to access methods.
17
* Method-level annotations override class-level when they conflict.
18
*/
19
@Target({TYPE, METHOD})
20
@Retention(RUNTIME)
21
public @interface RolesAllowed {
22
/**
23
* List of security role names that are permitted access.
24
*/
25
String[] value();
26
}
27
```
28
29
**Usage Examples:**
30
31
```java
32
import jakarta.annotation.security.RolesAllowed;
33
34
// Class-level: applies to all methods unless overridden
35
@RolesAllowed({"user", "admin"})
36
public class DocumentService {
37
38
// Inherits class-level roles: user, admin
39
public List<Document> getDocuments() {
40
return documentRepository.findAll();
41
}
42
43
// Method-level override: only admin can access
44
@RolesAllowed("admin")
45
public void deleteDocument(String id) {
46
documentRepository.delete(id);
47
}
48
49
// Multiple roles allowed
50
@RolesAllowed({"admin", "manager", "supervisor"})
51
public void approveDocument(String id) {
52
documentRepository.approve(id);
53
}
54
}
55
```
56
57
#### @DenyAll
58
59
Specifies that no security roles are allowed to invoke the specified method(s). Effectively blocks all access to the annotated element.
60
61
```java { .api }
62
/**
63
* Denies access to all security roles.
64
* No users can access the annotated method(s).
65
*/
66
@Target({TYPE, METHOD})
67
@Retention(RUNTIME)
68
public @interface DenyAll {
69
}
70
```
71
72
**Usage Examples:**
73
74
```java
75
import jakarta.annotation.security.DenyAll;
76
import jakarta.annotation.security.RolesAllowed;
77
78
@RolesAllowed("user")
79
public class UserService {
80
81
// Normal access for users
82
public User getProfile() {
83
return currentUser;
84
}
85
86
// Completely blocked - no one can access
87
@DenyAll
88
public void dangerousOperation() {
89
// This method is completely inaccessible
90
}
91
92
// Method-level DenyAll overrides class-level RolesAllowed
93
@DenyAll
94
public void maintenanceMethod() {
95
// Blocked during refactoring/maintenance
96
}
97
}
98
```
99
100
#### @PermitAll
101
102
Specifies that all security roles are allowed to invoke the specified method(s). Makes methods "unchecked" - accessible to any authenticated user.
103
104
```java { .api }
105
/**
106
* Permits access to all security roles.
107
* Makes methods "unchecked" - accessible to any authenticated user.
108
* Can override @RolesAllowed when applied at method level.
109
*/
110
@Target({TYPE, METHOD})
111
@Retention(RUNTIME)
112
public @interface PermitAll {
113
}
114
```
115
116
**Usage Examples:**
117
118
```java
119
import jakarta.annotation.security.PermitAll;
120
import jakarta.annotation.security.RolesAllowed;
121
122
@RolesAllowed("admin")
123
public class AdminService {
124
125
// Only admin access (inherits from class)
126
public void manageUsers() {
127
// Admin-only operation
128
}
129
130
// Override class restriction: anyone can access
131
@PermitAll
132
public String getServerStatus() {
133
return "Server is running";
134
}
135
136
// Public utility method
137
@PermitAll
138
public String getVersion() {
139
return "1.0.0";
140
}
141
}
142
143
// Class-level PermitAll
144
@PermitAll
145
public class PublicService {
146
// All methods are publicly accessible
147
public String getInfo() { return "Public info"; }
148
public List<String> getNews() { return news; }
149
}
150
```
151
152
### Role Declaration and Identity Management
153
154
Annotations for declaring security roles and execution identity.
155
156
#### @DeclareRoles
157
158
Declares security roles used by the application. Specifies the complete list of security role names that the application recognizes.
159
160
```java { .api }
161
/**
162
* Declares security roles used by the application.
163
* Specifies the complete list of security role names.
164
*/
165
@Target(TYPE)
166
@Retention(RUNTIME)
167
public @interface DeclareRoles {
168
/**
169
* List of security role names used by the application.
170
*/
171
String[] value();
172
}
173
```
174
175
**Usage Examples:**
176
177
```java
178
import jakarta.annotation.security.DeclareRoles;
179
import jakarta.annotation.security.RolesAllowed;
180
181
// Declare all roles used in the application
182
@DeclareRoles({"admin", "manager", "employee", "guest"})
183
public class CorporateApplication {
184
185
@RolesAllowed({"admin", "manager"})
186
public void accessFinancialData() {
187
// Management-level access
188
}
189
190
@RolesAllowed("employee")
191
public void clockIn() {
192
// Employee functionality
193
}
194
}
195
196
// Multiple applications can declare different role sets
197
@DeclareRoles({"customer", "support", "billing"})
198
public class CustomerPortal {
199
// Customer-facing application with different roles
200
}
201
```
202
203
#### @RunAs
204
205
Defines the identity under which the application executes. Allows applications to run under a specific security role that must be mapped to the container's security realm.
206
207
**Important**: The role must map to the user/group information in the container's security realm.
208
209
```java { .api }
210
/**
211
* Defines execution identity for the application.
212
* Specifies the security role under which the application runs.
213
*/
214
@Target(TYPE)
215
@Retention(RUNTIME)
216
public @interface RunAs {
217
/**
218
* Name of the security role for execution identity.
219
* Must be mapped to the container's security realm.
220
*/
221
String value();
222
}
223
```
224
225
**Usage Examples:**
226
227
```java
228
import jakarta.annotation.security.RunAs;
229
import jakarta.annotation.security.RolesAllowed;
230
231
// Service runs with system privileges
232
@RunAs("system")
233
public class BackgroundJobService {
234
235
// Even though this requires admin role,
236
// it runs with system identity
237
@RolesAllowed("admin")
238
public void performSystemMaintenance() {
239
// Executes with system privileges
240
}
241
242
public void processScheduledTasks() {
243
// Runs as system user
244
}
245
}
246
247
// Data access service with database role
248
@RunAs("db-reader")
249
public class ReportingService {
250
251
public List<Report> generateReports() {
252
// Executes database queries with db-reader identity
253
return reportRepository.findAll();
254
}
255
}
256
257
// Integration service with external system identity
258
@RunAs("integration-user")
259
public class ExternalAPIService {
260
261
public void syncWithExternalSystem() {
262
// Calls external APIs with integration-user credentials
263
}
264
}
265
```
266
267
## Security Patterns and Best Practices
268
269
### Hierarchical Security
270
271
```java
272
import jakarta.annotation.security.*;
273
274
@DeclareRoles({"admin", "manager", "employee"})
275
@RolesAllowed("employee") // Base access level
276
public class ProjectService {
277
278
// All employees can view
279
public List<Project> getProjects() {
280
return projectRepository.findAll();
281
}
282
283
// Managers and admins can create
284
@RolesAllowed({"manager", "admin"})
285
public Project createProject(ProjectData data) {
286
return projectRepository.save(new Project(data));
287
}
288
289
// Only admins can delete
290
@RolesAllowed("admin")
291
public void deleteProject(String id) {
292
projectRepository.delete(id);
293
}
294
295
// Blocked during maintenance
296
@DenyAll
297
public void experimentalFeature() {
298
// Under development
299
}
300
}
301
```
302
303
### Mixed Security Approaches
304
305
```java
306
@RolesAllowed("user")
307
public class HybridService {
308
309
// Public health check
310
@PermitAll
311
public String healthCheck() {
312
return "OK";
313
}
314
315
// User-level access (inherits from class)
316
public UserProfile getProfile() {
317
return userService.getCurrentUser();
318
}
319
320
// Admin-only operations
321
@RolesAllowed("admin")
322
public void resetUserPassword(String userId) {
323
userService.resetPassword(userId);
324
}
325
326
// Completely blocked
327
@DenyAll
328
public void legacyMethod() {
329
// Deprecated and disabled
330
}
331
}
332
```