Swagger Core annotations library providing OpenAPI 3.x annotations for Java applications, enabling developers to document REST APIs with metadata annotations
—
This document covers annotations for configuring authentication and authorization schemes, including API keys, OAuth2, OpenID Connect, mutual TLS, and security requirements.
import io.swagger.v3.oas.annotations.security.SecurityScheme;
import io.swagger.v3.oas.annotations.security.SecuritySchemes;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.security.SecurityRequirements;
import io.swagger.v3.oas.annotations.security.OAuthFlow;
import io.swagger.v3.oas.annotations.security.OAuthFlows;
import io.swagger.v3.oas.annotations.security.OAuthScope;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn;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.
@SecurityScheme(
name = "apiKey",
description = "API key authentication via X-API-Key header",
type = SecuritySchemeType.APIKEY,
in = SecuritySchemeIn.HEADER,
paramName = "X-API-Key",
extensions = {
@Extension(name = "x-example", properties = {
@ExtensionProperty(name = "value", value = "your-api-key-here")
})
}
)
@SecurityScheme(
name = "queryApiKey",
description = "API key authentication via query parameter",
type = SecuritySchemeType.APIKEY,
in = SecuritySchemeIn.QUERY,
paramName = "api_key"
)
@SecurityScheme(
name = "cookieAuth",
description = "API key authentication via cookie",
type = SecuritySchemeType.APIKEY,
in = SecuritySchemeIn.COOKIE,
paramName = "session_token"
)// Basic Authentication
@SecurityScheme(
name = "basicAuth",
description = "HTTP Basic authentication using username and password",
type = SecuritySchemeType.HTTP,
scheme = "basic"
)
// Bearer Token Authentication (JWT)
@SecurityScheme(
name = "bearerAuth",
description = "JWT token authentication via Authorization header",
type = SecuritySchemeType.HTTP,
scheme = "bearer",
bearerFormat = "JWT",
extensions = {
@Extension(name = "x-token-type", properties = {
@ExtensionProperty(name = "type", value = "JWT"),
@ExtensionProperty(name = "algorithm", value = "HS256")
})
}
)
// Custom HTTP Scheme
@SecurityScheme(
name = "customAuth",
description = "Custom HTTP authentication scheme",
type = SecuritySchemeType.HTTP,
scheme = "digest"
)@SecurityScheme(
name = "oauth2",
description = "OAuth2 authentication with multiple flow support",
type = SecuritySchemeType.OAUTH2,
flows = @OAuthFlows(
authorizationCode = @OAuthFlow(
authorizationUrl = "https://auth.petstore.io/oauth/authorize",
tokenUrl = "https://auth.petstore.io/oauth/token",
refreshUrl = "https://auth.petstore.io/oauth/refresh",
scopes = {
@OAuthScope(name = "read", description = "Read access to resources"),
@OAuthScope(name = "write", description = "Write access to resources"),
@OAuthScope(name = "admin", description = "Administrative access")
}
),
implicit = @OAuthFlow(
authorizationUrl = "https://auth.petstore.io/oauth/authorize",
scopes = {
@OAuthScope(name = "read", description = "Read access to resources"),
@OAuthScope(name = "write", description = "Write access to resources")
}
),
password = @OAuthFlow(
tokenUrl = "https://auth.petstore.io/oauth/token",
refreshUrl = "https://auth.petstore.io/oauth/refresh",
scopes = {
@OAuthScope(name = "read", description = "Read access to resources"),
@OAuthScope(name = "write", description = "Write access to resources"),
@OAuthScope(name = "admin", description = "Administrative access")
}
),
clientCredentials = @OAuthFlow(
tokenUrl = "https://auth.petstore.io/oauth/token",
scopes = {
@OAuthScope(name = "api_access", description = "API access for applications"),
@OAuthScope(name = "system_admin", description = "System administration access")
}
)
)
)@SecurityScheme(
name = "openIdConnect",
description = "OpenID Connect authentication",
type = SecuritySchemeType.OPENIDCONNECT,
openIdConnectUrl = "https://auth.petstore.io/.well-known/openid-configuration",
extensions = {
@Extension(name = "x-client-id", properties = {
@ExtensionProperty(name = "value", value = "petstore-client")
}),
@Extension(name = "x-audience", properties = {
@ExtensionProperty(name = "value", value = "https://api.petstore.io")
})
}
)@SecurityScheme(
name = "mutualTLS",
description = "Mutual TLS authentication using client certificates",
type = SecuritySchemeType.MUTUALTLS,
extensions = {
@Extension(name = "x-certificate-requirements", properties = {
@ExtensionProperty(name = "issuer", value = "CN=Pet Store CA"),
@ExtensionProperty(name = "keyUsage", value = "digitalSignature, keyEncipherment")
})
}
)@SecuritySchemes({
@SecurityScheme(
name = "apiKeyAuth",
type = SecuritySchemeType.APIKEY,
in = SecuritySchemeIn.HEADER,
paramName = "X-API-Key"
),
@SecurityScheme(
name = "bearerAuth",
type = SecuritySchemeType.HTTP,
scheme = "bearer",
bearerFormat = "JWT"
),
@SecurityScheme(
name = "oauth2Auth",
type = SecuritySchemeType.OAUTH2,
flows = @OAuthFlows(
authorizationCode = @OAuthFlow(
authorizationUrl = "https://auth.example.com/oauth/authorize",
tokenUrl = "https://auth.example.com/oauth/token",
scopes = {
@OAuthScope(name = "read", description = "Read access"),
@OAuthScope(name = "write", description = "Write access")
}
)
)
)
})
@RestController
public class SecureApiController {
// Controller implementation
}public @interface SecurityScheme {
SecuritySchemeType type();
String name() default "";
String description() default "";
String paramName() default "";
SecuritySchemeIn in() default SecuritySchemeIn.DEFAULT;
String scheme() default "";
String bearerFormat() default "";
OAuthFlows flows() default @OAuthFlows;
String openIdConnectUrl() default "";
Extension[] extensions() default {};
String ref() default "";
}Defines security requirements for operations or the entire API. Can specify multiple schemes and required scopes.
@GetMapping("/pets")
@Operation(summary = "List all pets")
@SecurityRequirement(name = "apiKey")
public ResponseEntity<List<Pet>> getAllPets() {
return ResponseEntity.ok(petService.findAll());
}
// OAuth2 with specific scopes
@PostMapping("/pets")
@Operation(summary = "Create a new pet")
@SecurityRequirement(name = "oauth2", scopes = {"write", "pets:create"})
public ResponseEntity<Pet> createPet(@RequestBody Pet pet) {
return ResponseEntity.ok(petService.create(pet));
}
// Admin operation requiring elevated privileges
@DeleteMapping("/pets/{id}")
@Operation(summary = "Delete a pet")
@SecurityRequirement(name = "oauth2", scopes = {"admin", "pets:delete"})
public ResponseEntity<Void> deletePet(@PathVariable Long id) {
petService.delete(id);
return ResponseEntity.noContent().build();
}@GetMapping("/pets/{id}")
@Operation(summary = "Get pet by ID")
@SecurityRequirements({
@SecurityRequirement(name = "apiKey"),
@SecurityRequirement(name = "bearerAuth"),
@SecurityRequirement(name = "oauth2", scopes = {"read"})
})
public ResponseEntity<Pet> getPetById(@PathVariable Long id) {
// Can be authenticated with ANY of the above schemes
return ResponseEntity.ok(petService.findById(id));
}// Requires BOTH API key AND OAuth2 token
@PostMapping("/admin/pets/bulk-import")
@Operation(summary = "Bulk import pets (admin only)")
@SecurityRequirement(name = "apiKey") // AND
@SecurityRequirement(name = "oauth2", scopes = {"admin", "bulk_operations"}) // AND this
public ResponseEntity<BulkImportResult> bulkImportPets(@RequestBody List<Pet> pets) {
// Requires both authentication methods
return ResponseEntity.ok(petService.bulkImport(pets));
}@OpenAPIDefinition(
info = @Info(title = "Secure Pet Store API", version = "1.0.0"),
security = {
@SecurityRequirement(name = "apiKey"),
@SecurityRequirement(name = "oauth2", scopes = {"read"})
}
)
@RestController
public class PetStoreController {
// This endpoint inherits API-level security
@GetMapping("/pets")
public ResponseEntity<List<Pet>> getAllPets() {
return ResponseEntity.ok(petService.findAll());
}
// This endpoint overrides API-level security
@GetMapping("/pets/public")
@Operation(security = {}) // No security required
public ResponseEntity<List<Pet>> getPublicPets() {
return ResponseEntity.ok(petService.findPublicPets());
}
// This endpoint adds additional security requirements
@PostMapping("/pets")
@SecurityRequirement(name = "oauth2", scopes = {"write"})
public ResponseEntity<Pet> createPet(@RequestBody Pet pet) {
// Requires API-level security AND write scope
return ResponseEntity.ok(petService.create(pet));
}
}@RestController
public class FlexibleSecurityController {
@GetMapping("/pets/search")
@Operation(summary = "Search pets with optional authentication")
@SecurityRequirements({
@SecurityRequirement(name = "none"), // No authentication
@SecurityRequirement(name = "apiKey"), // OR API key
@SecurityRequirement(name = "oauth2", scopes = {"read"}) // OR OAuth2
})
public ResponseEntity<List<Pet>> searchPets(
@RequestParam(required = false) String query,
@RequestParam(required = false) Boolean includePrivate
) {
// Authentication affects available data
if (includePrivate != null && includePrivate) {
// Requires authentication for private pets
return ResponseEntity.ok(petService.searchIncludingPrivate(query));
}
return ResponseEntity.ok(petService.searchPublic(query));
}
}Define comprehensive OAuth2 flow configurations with detailed scope definitions.
@SecurityScheme(
name = "petStoreOAuth",
type = SecuritySchemeType.OAUTH2,
description = "Pet Store OAuth2 authentication with comprehensive flow support",
flows = @OAuthFlows(
authorizationCode = @OAuthFlow(
authorizationUrl = "https://auth.petstore.io/oauth/authorize",
tokenUrl = "https://auth.petstore.io/oauth/token",
refreshUrl = "https://auth.petstore.io/oauth/refresh",
scopes = {
@OAuthScope(
name = "pets:read",
description = "Read access to pet information"
),
@OAuthScope(
name = "pets:write",
description = "Create and update pet information"
),
@OAuthScope(
name = "pets:delete",
description = "Delete pet records"
),
@OAuthScope(
name = "categories:read",
description = "Read pet categories"
),
@OAuthScope(
name = "categories:manage",
description = "Create, update, and delete pet categories"
),
@OAuthScope(
name = "users:read",
description = "Read user profiles"
),
@OAuthScope(
name = "users:manage",
description = "Manage user accounts"
),
@OAuthScope(
name = "orders:read",
description = "Read order information"
),
@OAuthScope(
name = "orders:create",
description = "Create new orders"
),
@OAuthScope(
name = "admin",
description = "Full administrative access to all resources"
)
}
),
implicit = @OAuthFlow(
authorizationUrl = "https://auth.petstore.io/oauth/authorize",
scopes = {
@OAuthScope(name = "pets:read", description = "Read pet information"),
@OAuthScope(name = "pets:write", description = "Write pet information"),
@OAuthScope(name = "orders:read", description = "Read orders"),
@OAuthScope(name = "orders:create", description = "Create orders")
}
),
password = @OAuthFlow(
tokenUrl = "https://auth.petstore.io/oauth/token",
refreshUrl = "https://auth.petstore.io/oauth/refresh",
scopes = {
@OAuthScope(name = "pets:read", description = "Read pet information"),
@OAuthScope(name = "pets:write", description = "Write pet information"),
@OAuthScope(name = "users:read", description = "Read user profiles"),
@OAuthScope(name = "admin", description = "Administrative access")
}
),
clientCredentials = @OAuthFlow(
tokenUrl = "https://auth.petstore.io/oauth/token",
scopes = {
@OAuthScope(
name = "api:access",
description = "Basic API access for client applications"
),
@OAuthScope(
name = "webhook:receive",
description = "Receive webhook notifications"
),
@OAuthScope(
name = "system:monitor",
description = "Monitor system health and metrics"
)
}
)
)
)@RestController
public class ScopedPetController {
@GetMapping("/pets")
@SecurityRequirement(name = "petStoreOAuth", scopes = {"pets:read"})
public ResponseEntity<List<Pet>> getAllPets() {
return ResponseEntity.ok(petService.findAll());
}
@PostMapping("/pets")
@SecurityRequirement(name = "petStoreOAuth", scopes = {"pets:write"})
public ResponseEntity<Pet> createPet(@RequestBody Pet pet) {
return ResponseEntity.ok(petService.create(pet));
}
@PutMapping("/pets/{id}")
@SecurityRequirement(name = "petStoreOAuth", scopes = {"pets:write"})
public ResponseEntity<Pet> updatePet(@PathVariable Long id, @RequestBody Pet pet) {
return ResponseEntity.ok(petService.update(id, pet));
}
@DeleteMapping("/pets/{id}")
@SecurityRequirement(name = "petStoreOAuth", scopes = {"pets:delete"})
public ResponseEntity<Void> deletePet(@PathVariable Long id) {
petService.delete(id);
return ResponseEntity.noContent().build();
}
@GetMapping("/admin/pets/analytics")
@SecurityRequirement(name = "petStoreOAuth", scopes = {"admin"})
public ResponseEntity<PetAnalytics> getPetAnalytics() {
return ResponseEntity.ok(petService.getAnalytics());
}
@PostMapping("/pets/batch")
@SecurityRequirement(name = "petStoreOAuth", scopes = {"pets:write", "admin"})
public ResponseEntity<List<Pet>> batchCreatePets(@RequestBody List<Pet> pets) {
// Requires both pets:write AND admin scopes
return ResponseEntity.ok(petService.batchCreate(pets));
}
}Defines the type of security scheme being used.
public enum SecuritySchemeType {
DEFAULT,
APIKEY, // API key authentication
HTTP, // HTTP authentication (Basic, Bearer, etc.)
OAUTH2, // OAuth 2.0 authentication
OPENIDCONNECT, // OpenID Connect authentication
MUTUALTLS // Mutual TLS authentication
}Defines where the security parameter is located in HTTP requests.
public enum SecuritySchemeIn {
DEFAULT,
HEADER, // HTTP header
QUERY, // Query parameter
COOKIE // HTTP cookie
}@SecuritySchemes({
@SecurityScheme(
name = "tenantApiKey",
type = SecuritySchemeType.APIKEY,
in = SecuritySchemeIn.HEADER,
paramName = "X-Tenant-API-Key",
description = "Tenant-specific API key authentication"
),
@SecurityScheme(
name = "userBearer",
type = SecuritySchemeType.HTTP,
scheme = "bearer",
bearerFormat = "JWT",
description = "User JWT token with tenant context"
)
})
@RestController
public class MultiTenantController {
@GetMapping("/tenant/{tenantId}/pets")
@SecurityRequirements({
@SecurityRequirement(name = "tenantApiKey"),
@SecurityRequirement(name = "userBearer")
})
public ResponseEntity<List<Pet>> getTenantPets(@PathVariable String tenantId) {
return ResponseEntity.ok(petService.findByTenant(tenantId));
}
}@SecurityScheme(
name = "roleBasedAuth",
type = SecuritySchemeType.OAUTH2,
flows = @OAuthFlows(
authorizationCode = @OAuthFlow(
authorizationUrl = "https://auth.petstore.io/oauth/authorize",
tokenUrl = "https://auth.petstore.io/oauth/token",
scopes = {
@OAuthScope(name = "role:viewer", description = "Read-only access"),
@OAuthScope(name = "role:editor", description = "Read and write access"),
@OAuthScope(name = "role:admin", description = "Full administrative access"),
@OAuthScope(name = "role:owner", description = "Resource ownership privileges")
}
)
)
)
@RestController
public class RoleBasedController {
@GetMapping("/pets/{id}")
@SecurityRequirement(name = "roleBasedAuth", scopes = {"role:viewer"})
public ResponseEntity<Pet> viewPet(@PathVariable Long id) {
return ResponseEntity.ok(petService.findById(id));
}
@PutMapping("/pets/{id}")
@SecurityRequirement(name = "roleBasedAuth", scopes = {"role:editor"})
public ResponseEntity<Pet> editPet(@PathVariable Long id, @RequestBody Pet pet) {
return ResponseEntity.ok(petService.update(id, pet));
}
@DeleteMapping("/pets/{id}")
@SecurityRequirement(name = "roleBasedAuth", scopes = {"role:owner"})
public ResponseEntity<Void> deletePet(@PathVariable Long id) {
petService.delete(id);
return ResponseEntity.noContent().build();
}
}@SecurityScheme(
name = "temporaryAccess",
type = SecuritySchemeType.HTTP,
scheme = "bearer",
bearerFormat = "JWT",
description = "Temporary access token with expiration",
extensions = {
@Extension(name = "x-token-expiry", properties = {
@ExtensionProperty(name = "defaultDuration", value = "3600"),
@ExtensionProperty(name = "maxDuration", value = "86400")
}),
@Extension(name = "x-refresh-strategy", properties = {
@ExtensionProperty(name = "automatic", value = "true"),
@ExtensionProperty(name = "refreshBeforeExpiry", value = "300")
})
}
)Install with Tessl CLI
npx tessl i tessl/maven-io-swagger-core-v3--swagger-annotations