I'm using Springdoc (1.4.8) to document our Rest API. 99% of the calls are secured using an OAuth2 Bearer Token so I'd like to add it by default like this:
new OpenAPI()
.components(new Components()
.addSecuritySchemes("bearerTokenScheme",
new SecurityScheme()
.type(SecurityScheme.Type.HTTP)
.name("bearerTokenScheme")
.scheme("Bearer")
.bearerFormat("JWT")
)
)
.addSecurityItem(new SecurityRequirement()
.addList("bearerTokenScheme")
)
This works fine to have it specified by default, but my question is now, can I somehow overrule it by specifying a single call to be unsecured?
I do realize that omitting .addSecurityItem() will show calls as unsecured by default, but I'd like to have them secured by default and only having to override it when unsecured.
I had a similar issue and I have solved it using a plugin. The plugin overrides the security value of tagged controllers or methods and sets it to empty list. So the tagged endpoints remain unsecured.
@Component
public class NoSecurityPlugin implements OpenApiCustomiser {
private static final List<Function<PathItem, Operation>> OPERATION_GETTERS = Arrays.asList(
PathItem::getGet, PathItem::getPost, PathItem::getPut, PathItem::getDelete,
PathItem::getHead, PathItem::getOptions, PathItem::getPatch);
private static final List<String> tagsForNoSecurity = List.of(
"public", "unsecured"
);
@Override
public void customise(OpenAPI openApi) {
openApi.getPaths().forEach((path, item) -> getOperations(item).forEach(api -> {
List<String> tags = api.getTags();
if(tags != null && tags.stream().anyMatch(tagsForNoSecurity::contains)) {
api.setSecurity(Collections.emptyList());
}
}));
}
private static Stream<Operation> getOperations(PathItem pathItem) {
return OPERATION_GETTERS.stream()
.map(g -> g.apply(pathItem))
.filter(Objects::nonNull);
}
}
Tag your API methods (or Controller):
@Tag(name = "public", description = "Public APIs")