Cor*_*ndt 15 java spring swagger openapi springdoc
我SecurityScheme
对 java SpringBoot RESTful 应用程序使用 springdoc-openapi有以下定义:
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.components(new Components().addSecuritySchemes("bearer-jwt",
new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT")
.in(SecurityScheme.In.HEADER).name("Authorization")))
.info(new Info().title("App API").version("snapshot"));
}
Run Code Online (Sandbox Code Playgroud)
是否可以将其全局应用于所有路径,而不必在代码中的任何地方添加@SecurityRequirement
注释@Operation
?
如果是,如何向不安全的路径添加排除项?
Maf*_*for 23
是的,您可以在同一个地方调用addSecurityItem
:
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.components(new Components().addSecuritySchemes("bearer-jwt",
new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT")
.in(SecurityScheme.In.HEADER).name("Authorization")))
.info(new Info().title("App API").version("snapshot"))
.addSecurityItem(
new SecurityRequirement().addList("bearer-jwt", Arrays.asList("read", "write")));
}
Run Code Online (Sandbox Code Playgroud)
全局安全模式可以被带有@SecurityRequirements
注释的不同模式覆盖。包括删除操作的安全模式。例如,我们可以删除注册路径的安全性。
@SecurityRequirements
@PostMapping("/registration")
public ResponseEntity post(@RequestBody @Valid Registration: registration) {
return registrationService.register(registration);
}
Run Code Online (Sandbox Code Playgroud)
同时仍为其他 API 保留安全模式。
旧答案(19 年 12 月 20 日):
全局安全模式可以被带有@SecurityRequirements
注释的不同模式覆盖。但对于不安全的路径,它不能被删除。它在springdoc-openapi中确实缺少 fueature ,OpenAPI 标准允许它。请参阅禁用特定操作的全局安全性
不过有一个解决方法。所述springdoc-OpenAPI的具有可用于拦截生成的模式的OpenApiCustomiser的概念。在定制器内部,可以通过编程方式修改操作。要删除任何继承的安全性,该字段security
需要设置为空数组。该逻辑可以基于任何任意规则,例如操作名称。我使用了标签。
定制师:
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem;
import org.springdoc.api.OpenApiCustomiser;
import org.springframework.stereotype.Component;
import javax.validation.constraints.NotNull;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Component
public class SecurityOverrideCustomizer implements OpenApiCustomiser {
public static final String UNSECURED = "security.open";
private static final List<Function<PathItem, Operation>> OPERATION_GETTERS = Arrays.asList(
PathItem::getGet, PathItem::getPost, PathItem::getDelete, PathItem::getHead,
PathItem::getOptions, PathItem::getPatch, PathItem::getPut);
@Override
public void customise(OpenAPI openApi) {
openApi.getPaths().forEach((path, item) -> getOperations(item).forEach(operation -> {
List<String> tags = operation.getTags();
if (tags != null && tags.contains(UNSECURED)) {
operation.setSecurity(Collections.emptyList());
operation.setTags(filterTags(tags));
}
}));
}
private static Stream<Operation> getOperations(PathItem pathItem) {
return OPERATION_GETTERS.stream()
.map(getter -> getter.apply(pathItem))
.filter(Objects::nonNull);
}
private static List<String> filterTags(List<String> tags) {
return tags.stream()
.filter(t -> !t.equals(UNSECURED))
.collect(Collectors.toList());
}
}
Run Code Online (Sandbox Code Playgroud)
现在我们可以添加@Tag(name = SecurityOverrideCustomizer.UNSECURED)
不安全的方法:
@Tag(name = SecurityOverrideCustomizer.UNSECURED)
@GetMapping("/open")
@ResponseBody
public String open() {
return "It works!";
}
Run Code Online (Sandbox Code Playgroud)
请记住,这只是一种解决方法。希望该问题将在下一个springdoc-openapi版本中得到解决(在撰写本文时,当前版本为 1.2.18)。
有关工作示例,请参阅springdoc-security-override-fix
小智 5
使用 springdoc-openapi 的 v1.2.29 测试:可以使用以下方法禁用特定端点的安全性:@SecurityRequirements
@GetMapping("/open")
@ResponseBody
@SecurityRequirements
public String open() {
return "It works!";
}
Run Code Online (Sandbox Code Playgroud)
对于旧版本,例如使用 OperationCustomizer 使用 v1.2.28 进行测试:
public static final String UNSECURED = "security.open";
@Bean
public OperationCustomizer customize() {
return (Operation operation, HandlerMethod handlerMethod) -> {
List<String> tags = operation.getTags();
if (tags != null && tags.contains(UNSECURED)) {
operation.setSecurity(Collections.emptyList());
operation.setTags(tags.stream()
.filter(t -> !t.equals(UNSECURED))
.collect(Collectors.toList()));
}
return operation;
};
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8404 次 |
最近记录: |