I am using swagger.core.v3 in version 2.0.2 to generate openAPI 3.0 definition files and
I am having trouble to disable "security" for a particular endpoint.
I have global securitySchemes and root security element defined:
Info info = new Info()
.title("someTitle")
.description("some description")
.version("1.0")
SecurityScheme jwtSecurity = new SecurityScheme()
.type(SecurityScheme.Type.HTTP)
.name("Authorization")
.in(SecurityScheme.In.HEADER)
.scheme("bearer")
.bearerFormat("JWT");
String securitySchemaName = "JWT";
OpenAPI oas = new OpenAPI()
.info(info)
.components(new Components().addSecuritySchemes(securitySchemaName, jwtSecurity))
.addSecurityItem(new SecurityRequirement().addList(securitySchemaName));
SwaggerConfiguration oasConfig = new SwaggerConfiguration()
.openAPI(oas)
.prettyPrint(true)
.resourcePackages(Stream.of("my.resources.package")
.collect(Collectors.toSet()));
environment.jersey().register(new OpenApiResource()
.openApiConfiguration(oasConfig));
And definition file is nicely generated:
{
"openapi" : "3.0.1",
"security" : [ {
"JWT" : [ ]
} ],
"paths" : {
...
},
"components" : {
"schemas" : {
...
},
"securitySchemes" : {
"JWT" : {
"type" : "http",
"scheme" : "bearer",
"bearerFormat" : "JWT"
}
}
}
}
According to OPEN API 3 spec https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md#securityRequirementObject i shall be able to override global "security requirement" for an individual operation. I would like to "disable" JWT security for a few operations and according to https://github.com/OAI/OpenAPI-Specification/blob/3.0.1/versions/3.0.1.md#securityRequirementObject it can be done by
To remove a top-level security declaration, an empty array can be used.
I simply wanna specify "NO Security" for a particular opetration:
@POST
@Operation(
summary = "authenticate user",
responses = {
@ApiResponse(responseCode = "200", description = "when user is successfully authenticated",
content = @Content(schema = @Schema(implementation = AuthenticateUserOutput.class))),
@ApiResponse(responseCode = "401", description = "when email/password not valid or user is blocked/inactive"),
}
,security = what to put here ?
)
I tried
security = {}
or
security = @SecurityRequirement(name ="")
but in both cases no security element within operation is generated at all....
at the moment you can achieve what you need using filter, as in the example below; possibly related annotation processing will be enhanced to allow for annotation only handling of such a case, but no ETA atm
class SecurityFilter extends AbstractSpecFilter {
@Override
public Optional<Operation> filterOperation(Operation operation, ApiDescription api, Map<String, List<String>> params, Map<String, String> cookies, Map<String, List<String>> headers) {
if ("security".equals(operation.getOperationId())) { // or whatever operationId..
operation.setSecurity(new ArrayList<>());
return Optional.of(operation);
}
return super.filterOperation(operation, api, params, cookies, headers);
}
}
in your case (usage of provided OpenApiResource
) you can specify filter providing fully qualified name in config object:
SwaggerConfiguration oasConfig = new SwaggerConfiguration()
.openAPI(oas)
.prettyPrint(true)
.filterClass("fully.qualified.SecurityFilter")
.resourcePackages(Stream.of("my.resources.package")
.collect(Collectors.toSet()));
Interestingly, it works on the SwaggerHub: security-override-test
bump
I found that simply adding io.swagger.v3.oas.annotations.security.SecurityRequirements
as an annotation will do what you want.
@RestController
class Controller {
@SecurityRequirements // This is it
@GetMapping("/api/v1/endpoint")
public String endpoint() {
return "no security required!";
}
}
At least for me this disabled all security requirements for the method.
Most helpful comment
I found that simply adding
io.swagger.v3.oas.annotations.security.SecurityRequirements
as an annotation will do what you want.At least for me this disabled all security requirements for the method.