0
# Security Configuration
1
2
This document covers annotations for configuring authentication and authorization schemes, including API keys, OAuth2, OpenID Connect, mutual TLS, and security requirements.
3
4
## Imports
5
6
```java { .api }
7
import io.swagger.v3.oas.annotations.security.SecurityScheme;
8
import io.swagger.v3.oas.annotations.security.SecuritySchemes;
9
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
10
import io.swagger.v3.oas.annotations.security.SecurityRequirements;
11
import io.swagger.v3.oas.annotations.security.OAuthFlow;
12
import io.swagger.v3.oas.annotations.security.OAuthFlows;
13
import io.swagger.v3.oas.annotations.security.OAuthScope;
14
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
15
import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn;
16
```
17
18
## SecurityScheme
19
20
Defines security schemes that can be used by operations or the entire API. Security schemes are added to the components section of the OpenAPI specification.
21
22
### API Key Authentication
23
24
```java { .api }
25
@SecurityScheme(
26
name = "apiKey",
27
description = "API key authentication via X-API-Key header",
28
type = SecuritySchemeType.APIKEY,
29
in = SecuritySchemeIn.HEADER,
30
paramName = "X-API-Key",
31
extensions = {
32
@Extension(name = "x-example", properties = {
33
@ExtensionProperty(name = "value", value = "your-api-key-here")
34
})
35
}
36
)
37
38
@SecurityScheme(
39
name = "queryApiKey",
40
description = "API key authentication via query parameter",
41
type = SecuritySchemeType.APIKEY,
42
in = SecuritySchemeIn.QUERY,
43
paramName = "api_key"
44
)
45
46
@SecurityScheme(
47
name = "cookieAuth",
48
description = "API key authentication via cookie",
49
type = SecuritySchemeType.APIKEY,
50
in = SecuritySchemeIn.COOKIE,
51
paramName = "session_token"
52
)
53
```
54
55
### HTTP Authentication Schemes
56
57
```java { .api }
58
// Basic Authentication
59
@SecurityScheme(
60
name = "basicAuth",
61
description = "HTTP Basic authentication using username and password",
62
type = SecuritySchemeType.HTTP,
63
scheme = "basic"
64
)
65
66
// Bearer Token Authentication (JWT)
67
@SecurityScheme(
68
name = "bearerAuth",
69
description = "JWT token authentication via Authorization header",
70
type = SecuritySchemeType.HTTP,
71
scheme = "bearer",
72
bearerFormat = "JWT",
73
extensions = {
74
@Extension(name = "x-token-type", properties = {
75
@ExtensionProperty(name = "type", value = "JWT"),
76
@ExtensionProperty(name = "algorithm", value = "HS256")
77
})
78
}
79
)
80
81
// Custom HTTP Scheme
82
@SecurityScheme(
83
name = "customAuth",
84
description = "Custom HTTP authentication scheme",
85
type = SecuritySchemeType.HTTP,
86
scheme = "digest"
87
)
88
```
89
90
### OAuth2 Authentication
91
92
```java { .api }
93
@SecurityScheme(
94
name = "oauth2",
95
description = "OAuth2 authentication with multiple flow support",
96
type = SecuritySchemeType.OAUTH2,
97
flows = @OAuthFlows(
98
authorizationCode = @OAuthFlow(
99
authorizationUrl = "https://auth.petstore.io/oauth/authorize",
100
tokenUrl = "https://auth.petstore.io/oauth/token",
101
refreshUrl = "https://auth.petstore.io/oauth/refresh",
102
scopes = {
103
@OAuthScope(name = "read", description = "Read access to resources"),
104
@OAuthScope(name = "write", description = "Write access to resources"),
105
@OAuthScope(name = "admin", description = "Administrative access")
106
}
107
),
108
implicit = @OAuthFlow(
109
authorizationUrl = "https://auth.petstore.io/oauth/authorize",
110
scopes = {
111
@OAuthScope(name = "read", description = "Read access to resources"),
112
@OAuthScope(name = "write", description = "Write access to resources")
113
}
114
),
115
password = @OAuthFlow(
116
tokenUrl = "https://auth.petstore.io/oauth/token",
117
refreshUrl = "https://auth.petstore.io/oauth/refresh",
118
scopes = {
119
@OAuthScope(name = "read", description = "Read access to resources"),
120
@OAuthScope(name = "write", description = "Write access to resources"),
121
@OAuthScope(name = "admin", description = "Administrative access")
122
}
123
),
124
clientCredentials = @OAuthFlow(
125
tokenUrl = "https://auth.petstore.io/oauth/token",
126
scopes = {
127
@OAuthScope(name = "api_access", description = "API access for applications"),
128
@OAuthScope(name = "system_admin", description = "System administration access")
129
}
130
)
131
)
132
)
133
```
134
135
### OpenID Connect
136
137
```java { .api }
138
@SecurityScheme(
139
name = "openIdConnect",
140
description = "OpenID Connect authentication",
141
type = SecuritySchemeType.OPENIDCONNECT,
142
openIdConnectUrl = "https://auth.petstore.io/.well-known/openid-configuration",
143
extensions = {
144
@Extension(name = "x-client-id", properties = {
145
@ExtensionProperty(name = "value", value = "petstore-client")
146
}),
147
@Extension(name = "x-audience", properties = {
148
@ExtensionProperty(name = "value", value = "https://api.petstore.io")
149
})
150
}
151
)
152
```
153
154
### Mutual TLS Authentication
155
156
```java { .api }
157
@SecurityScheme(
158
name = "mutualTLS",
159
description = "Mutual TLS authentication using client certificates",
160
type = SecuritySchemeType.MUTUALTLS,
161
extensions = {
162
@Extension(name = "x-certificate-requirements", properties = {
163
@ExtensionProperty(name = "issuer", value = "CN=Pet Store CA"),
164
@ExtensionProperty(name = "keyUsage", value = "digitalSignature, keyEncipherment")
165
})
166
}
167
)
168
```
169
170
### Multiple Security Schemes
171
172
```java { .api }
173
@SecuritySchemes({
174
@SecurityScheme(
175
name = "apiKeyAuth",
176
type = SecuritySchemeType.APIKEY,
177
in = SecuritySchemeIn.HEADER,
178
paramName = "X-API-Key"
179
),
180
@SecurityScheme(
181
name = "bearerAuth",
182
type = SecuritySchemeType.HTTP,
183
scheme = "bearer",
184
bearerFormat = "JWT"
185
),
186
@SecurityScheme(
187
name = "oauth2Auth",
188
type = SecuritySchemeType.OAUTH2,
189
flows = @OAuthFlows(
190
authorizationCode = @OAuthFlow(
191
authorizationUrl = "https://auth.example.com/oauth/authorize",
192
tokenUrl = "https://auth.example.com/oauth/token",
193
scopes = {
194
@OAuthScope(name = "read", description = "Read access"),
195
@OAuthScope(name = "write", description = "Write access")
196
}
197
)
198
)
199
)
200
})
201
@RestController
202
public class SecureApiController {
203
// Controller implementation
204
}
205
```
206
207
### SecurityScheme Attributes
208
209
```java { .api }
210
public @interface SecurityScheme {
211
SecuritySchemeType type();
212
String name() default "";
213
String description() default "";
214
String paramName() default "";
215
SecuritySchemeIn in() default SecuritySchemeIn.DEFAULT;
216
String scheme() default "";
217
String bearerFormat() default "";
218
OAuthFlows flows() default @OAuthFlows;
219
String openIdConnectUrl() default "";
220
Extension[] extensions() default {};
221
String ref() default "";
222
}
223
```
224
225
## SecurityRequirement
226
227
Defines security requirements for operations or the entire API. Can specify multiple schemes and required scopes.
228
229
### Single Security Requirement
230
231
```java { .api }
232
@GetMapping("/pets")
233
@Operation(summary = "List all pets")
234
@SecurityRequirement(name = "apiKey")
235
public ResponseEntity<List<Pet>> getAllPets() {
236
return ResponseEntity.ok(petService.findAll());
237
}
238
239
// OAuth2 with specific scopes
240
@PostMapping("/pets")
241
@Operation(summary = "Create a new pet")
242
@SecurityRequirement(name = "oauth2", scopes = {"write", "pets:create"})
243
public ResponseEntity<Pet> createPet(@RequestBody Pet pet) {
244
return ResponseEntity.ok(petService.create(pet));
245
}
246
247
// Admin operation requiring elevated privileges
248
@DeleteMapping("/pets/{id}")
249
@Operation(summary = "Delete a pet")
250
@SecurityRequirement(name = "oauth2", scopes = {"admin", "pets:delete"})
251
public ResponseEntity<Void> deletePet(@PathVariable Long id) {
252
petService.delete(id);
253
return ResponseEntity.noContent().build();
254
}
255
```
256
257
### Multiple Security Requirements (OR Logic)
258
259
```java { .api }
260
@GetMapping("/pets/{id}")
261
@Operation(summary = "Get pet by ID")
262
@SecurityRequirements({
263
@SecurityRequirement(name = "apiKey"),
264
@SecurityRequirement(name = "bearerAuth"),
265
@SecurityRequirement(name = "oauth2", scopes = {"read"})
266
})
267
public ResponseEntity<Pet> getPetById(@PathVariable Long id) {
268
// Can be authenticated with ANY of the above schemes
269
return ResponseEntity.ok(petService.findById(id));
270
}
271
```
272
273
### Combined Security Requirements (AND Logic)
274
275
```java { .api }
276
// Requires BOTH API key AND OAuth2 token
277
@PostMapping("/admin/pets/bulk-import")
278
@Operation(summary = "Bulk import pets (admin only)")
279
@SecurityRequirement(name = "apiKey") // AND
280
@SecurityRequirement(name = "oauth2", scopes = {"admin", "bulk_operations"}) // AND this
281
public ResponseEntity<BulkImportResult> bulkImportPets(@RequestBody List<Pet> pets) {
282
// Requires both authentication methods
283
return ResponseEntity.ok(petService.bulkImport(pets));
284
}
285
```
286
287
### API-Level Security
288
289
```java { .api }
290
@OpenAPIDefinition(
291
info = @Info(title = "Secure Pet Store API", version = "1.0.0"),
292
security = {
293
@SecurityRequirement(name = "apiKey"),
294
@SecurityRequirement(name = "oauth2", scopes = {"read"})
295
}
296
)
297
@RestController
298
public class PetStoreController {
299
300
// This endpoint inherits API-level security
301
@GetMapping("/pets")
302
public ResponseEntity<List<Pet>> getAllPets() {
303
return ResponseEntity.ok(petService.findAll());
304
}
305
306
// This endpoint overrides API-level security
307
@GetMapping("/pets/public")
308
@Operation(security = {}) // No security required
309
public ResponseEntity<List<Pet>> getPublicPets() {
310
return ResponseEntity.ok(petService.findPublicPets());
311
}
312
313
// This endpoint adds additional security requirements
314
@PostMapping("/pets")
315
@SecurityRequirement(name = "oauth2", scopes = {"write"})
316
public ResponseEntity<Pet> createPet(@RequestBody Pet pet) {
317
// Requires API-level security AND write scope
318
return ResponseEntity.ok(petService.create(pet));
319
}
320
}
321
```
322
323
### Conditional Security Based on Operation
324
325
```java { .api }
326
@RestController
327
public class FlexibleSecurityController {
328
329
@GetMapping("/pets/search")
330
@Operation(summary = "Search pets with optional authentication")
331
@SecurityRequirements({
332
@SecurityRequirement(name = "none"), // No authentication
333
@SecurityRequirement(name = "apiKey"), // OR API key
334
@SecurityRequirement(name = "oauth2", scopes = {"read"}) // OR OAuth2
335
})
336
public ResponseEntity<List<Pet>> searchPets(
337
@RequestParam(required = false) String query,
338
@RequestParam(required = false) Boolean includePrivate
339
) {
340
// Authentication affects available data
341
if (includePrivate != null && includePrivate) {
342
// Requires authentication for private pets
343
return ResponseEntity.ok(petService.searchIncludingPrivate(query));
344
}
345
return ResponseEntity.ok(petService.searchPublic(query));
346
}
347
}
348
```
349
350
## OAuthFlows and OAuthScope
351
352
Define comprehensive OAuth2 flow configurations with detailed scope definitions.
353
354
### Complete OAuth2 Configuration
355
356
```java { .api }
357
@SecurityScheme(
358
name = "petStoreOAuth",
359
type = SecuritySchemeType.OAUTH2,
360
description = "Pet Store OAuth2 authentication with comprehensive flow support",
361
flows = @OAuthFlows(
362
authorizationCode = @OAuthFlow(
363
authorizationUrl = "https://auth.petstore.io/oauth/authorize",
364
tokenUrl = "https://auth.petstore.io/oauth/token",
365
refreshUrl = "https://auth.petstore.io/oauth/refresh",
366
scopes = {
367
@OAuthScope(
368
name = "pets:read",
369
description = "Read access to pet information"
370
),
371
@OAuthScope(
372
name = "pets:write",
373
description = "Create and update pet information"
374
),
375
@OAuthScope(
376
name = "pets:delete",
377
description = "Delete pet records"
378
),
379
@OAuthScope(
380
name = "categories:read",
381
description = "Read pet categories"
382
),
383
@OAuthScope(
384
name = "categories:manage",
385
description = "Create, update, and delete pet categories"
386
),
387
@OAuthScope(
388
name = "users:read",
389
description = "Read user profiles"
390
),
391
@OAuthScope(
392
name = "users:manage",
393
description = "Manage user accounts"
394
),
395
@OAuthScope(
396
name = "orders:read",
397
description = "Read order information"
398
),
399
@OAuthScope(
400
name = "orders:create",
401
description = "Create new orders"
402
),
403
@OAuthScope(
404
name = "admin",
405
description = "Full administrative access to all resources"
406
)
407
}
408
),
409
implicit = @OAuthFlow(
410
authorizationUrl = "https://auth.petstore.io/oauth/authorize",
411
scopes = {
412
@OAuthScope(name = "pets:read", description = "Read pet information"),
413
@OAuthScope(name = "pets:write", description = "Write pet information"),
414
@OAuthScope(name = "orders:read", description = "Read orders"),
415
@OAuthScope(name = "orders:create", description = "Create orders")
416
}
417
),
418
password = @OAuthFlow(
419
tokenUrl = "https://auth.petstore.io/oauth/token",
420
refreshUrl = "https://auth.petstore.io/oauth/refresh",
421
scopes = {
422
@OAuthScope(name = "pets:read", description = "Read pet information"),
423
@OAuthScope(name = "pets:write", description = "Write pet information"),
424
@OAuthScope(name = "users:read", description = "Read user profiles"),
425
@OAuthScope(name = "admin", description = "Administrative access")
426
}
427
),
428
clientCredentials = @OAuthFlow(
429
tokenUrl = "https://auth.petstore.io/oauth/token",
430
scopes = {
431
@OAuthScope(
432
name = "api:access",
433
description = "Basic API access for client applications"
434
),
435
@OAuthScope(
436
name = "webhook:receive",
437
description = "Receive webhook notifications"
438
),
439
@OAuthScope(
440
name = "system:monitor",
441
description = "Monitor system health and metrics"
442
)
443
}
444
)
445
)
446
)
447
```
448
449
### Fine-Grained Scope Usage
450
451
```java { .api }
452
@RestController
453
public class ScopedPetController {
454
455
@GetMapping("/pets")
456
@SecurityRequirement(name = "petStoreOAuth", scopes = {"pets:read"})
457
public ResponseEntity<List<Pet>> getAllPets() {
458
return ResponseEntity.ok(petService.findAll());
459
}
460
461
@PostMapping("/pets")
462
@SecurityRequirement(name = "petStoreOAuth", scopes = {"pets:write"})
463
public ResponseEntity<Pet> createPet(@RequestBody Pet pet) {
464
return ResponseEntity.ok(petService.create(pet));
465
}
466
467
@PutMapping("/pets/{id}")
468
@SecurityRequirement(name = "petStoreOAuth", scopes = {"pets:write"})
469
public ResponseEntity<Pet> updatePet(@PathVariable Long id, @RequestBody Pet pet) {
470
return ResponseEntity.ok(petService.update(id, pet));
471
}
472
473
@DeleteMapping("/pets/{id}")
474
@SecurityRequirement(name = "petStoreOAuth", scopes = {"pets:delete"})
475
public ResponseEntity<Void> deletePet(@PathVariable Long id) {
476
petService.delete(id);
477
return ResponseEntity.noContent().build();
478
}
479
480
@GetMapping("/admin/pets/analytics")
481
@SecurityRequirement(name = "petStoreOAuth", scopes = {"admin"})
482
public ResponseEntity<PetAnalytics> getPetAnalytics() {
483
return ResponseEntity.ok(petService.getAnalytics());
484
}
485
486
@PostMapping("/pets/batch")
487
@SecurityRequirement(name = "petStoreOAuth", scopes = {"pets:write", "admin"})
488
public ResponseEntity<List<Pet>> batchCreatePets(@RequestBody List<Pet> pets) {
489
// Requires both pets:write AND admin scopes
490
return ResponseEntity.ok(petService.batchCreate(pets));
491
}
492
}
493
```
494
495
## Security Enums
496
497
### SecuritySchemeType
498
499
Defines the type of security scheme being used.
500
501
```java { .api }
502
public enum SecuritySchemeType {
503
DEFAULT,
504
APIKEY, // API key authentication
505
HTTP, // HTTP authentication (Basic, Bearer, etc.)
506
OAUTH2, // OAuth 2.0 authentication
507
OPENIDCONNECT, // OpenID Connect authentication
508
MUTUALTLS // Mutual TLS authentication
509
}
510
```
511
512
### SecuritySchemeIn
513
514
Defines where the security parameter is located in HTTP requests.
515
516
```java { .api }
517
public enum SecuritySchemeIn {
518
DEFAULT,
519
HEADER, // HTTP header
520
QUERY, // Query parameter
521
COOKIE // HTTP cookie
522
}
523
```
524
525
## Advanced Security Configurations
526
527
### Multi-Tenant Security
528
529
```java { .api }
530
@SecuritySchemes({
531
@SecurityScheme(
532
name = "tenantApiKey",
533
type = SecuritySchemeType.APIKEY,
534
in = SecuritySchemeIn.HEADER,
535
paramName = "X-Tenant-API-Key",
536
description = "Tenant-specific API key authentication"
537
),
538
@SecurityScheme(
539
name = "userBearer",
540
type = SecuritySchemeType.HTTP,
541
scheme = "bearer",
542
bearerFormat = "JWT",
543
description = "User JWT token with tenant context"
544
)
545
})
546
@RestController
547
public class MultiTenantController {
548
549
@GetMapping("/tenant/{tenantId}/pets")
550
@SecurityRequirements({
551
@SecurityRequirement(name = "tenantApiKey"),
552
@SecurityRequirement(name = "userBearer")
553
})
554
public ResponseEntity<List<Pet>> getTenantPets(@PathVariable String tenantId) {
555
return ResponseEntity.ok(petService.findByTenant(tenantId));
556
}
557
}
558
```
559
560
### Role-Based Access Control
561
562
```java { .api }
563
@SecurityScheme(
564
name = "roleBasedAuth",
565
type = SecuritySchemeType.OAUTH2,
566
flows = @OAuthFlows(
567
authorizationCode = @OAuthFlow(
568
authorizationUrl = "https://auth.petstore.io/oauth/authorize",
569
tokenUrl = "https://auth.petstore.io/oauth/token",
570
scopes = {
571
@OAuthScope(name = "role:viewer", description = "Read-only access"),
572
@OAuthScope(name = "role:editor", description = "Read and write access"),
573
@OAuthScope(name = "role:admin", description = "Full administrative access"),
574
@OAuthScope(name = "role:owner", description = "Resource ownership privileges")
575
}
576
)
577
)
578
)
579
580
@RestController
581
public class RoleBasedController {
582
583
@GetMapping("/pets/{id}")
584
@SecurityRequirement(name = "roleBasedAuth", scopes = {"role:viewer"})
585
public ResponseEntity<Pet> viewPet(@PathVariable Long id) {
586
return ResponseEntity.ok(petService.findById(id));
587
}
588
589
@PutMapping("/pets/{id}")
590
@SecurityRequirement(name = "roleBasedAuth", scopes = {"role:editor"})
591
public ResponseEntity<Pet> editPet(@PathVariable Long id, @RequestBody Pet pet) {
592
return ResponseEntity.ok(petService.update(id, pet));
593
}
594
595
@DeleteMapping("/pets/{id}")
596
@SecurityRequirement(name = "roleBasedAuth", scopes = {"role:owner"})
597
public ResponseEntity<Void> deletePet(@PathVariable Long id) {
598
petService.delete(id);
599
return ResponseEntity.noContent().build();
600
}
601
}
602
```
603
604
### Time-Limited Access Tokens
605
606
```java { .api }
607
@SecurityScheme(
608
name = "temporaryAccess",
609
type = SecuritySchemeType.HTTP,
610
scheme = "bearer",
611
bearerFormat = "JWT",
612
description = "Temporary access token with expiration",
613
extensions = {
614
@Extension(name = "x-token-expiry", properties = {
615
@ExtensionProperty(name = "defaultDuration", value = "3600"),
616
@ExtensionProperty(name = "maxDuration", value = "86400")
617
}),
618
@Extension(name = "x-refresh-strategy", properties = {
619
@ExtensionProperty(name = "automatic", value = "true"),
620
@ExtensionProperty(name = "refreshBeforeExpiry", value = "300")
621
})
622
}
623
)
624
```