对于java SpringBoot RESTful应用,我使用springdoc-openapi具有以下SecurityScheme定义:
function showDetails(REPORTNO, date1, date2, locid, cancelId) {
$.ajax({
url: "catdetail.php",
method: "POST",
async: true,
data: {
"REPORTNO": REPORTNO,
"date1": date1,
"date2": date2,
"locid": locid,
"cancelId": cancelId
},
success: function(response) {
var details = JSON.parse(response);
details.ushift(['Time', 'Qty']);
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable(details);
var options = {
title: 'Company Performance',
hAxis: {
title: 'Category Sales by Time',
titleTextStyle: {
color: '#333'
}
},
vAxis: {
minValue: 0
},
pointSize: 18,
pointShape: {
type: 'star',
sides: 5,
dent: 0.5
}
};
var chart = new google.visualization.AreaChart(document.getElementById('chart_detail'));
chart.draw(data, options);
});
}
});
};
是否可以将其全局应用到所有路径,而不必在代码中的任何地方都添加@SecuirtyRequirement注释到@Operation注释?
如果是,如何将排除项添加到不安全的路径中?
答案 0 :(得分:5)
在springdoc-openapi v1.2.29中进行了测试:可以使用@SecurityRequirements
来禁用特定端点的安全性@GetMapping("/open")
@ResponseBody
@SecurityRequirements
public String open() {
return "It works!";
}
对于旧版本,例如使用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;
};
}
答案 1 :(得分:2)
是的,您可以在调用arr
的位置进行操作:
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")));
}
批注的另一种覆盖全局安全性架构,但是对于不安全的路径则不能将其删除。在 springdoc-openapi 中,它突然失去了特性,OpenAPI标准允许它。参见disable global security for particular operation
但是有一种解决方法。 springdoc-openapi 具有OpenApiCustomiser的概念,可用于拦截生成的模式。在定制器内部,可以以编程方式修改操作。要删除任何继承的安全性,必须将字段@SecurityRequirements
设置为空数组。逻辑可以基于任何任意规则,例如操作名称。我用过标签。
定制程序:
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());
}
}
添加到不安全的方法中:
@Tag(name = SecurityOverrideCustomizer.UNSECURED)
请记住,这只是一种解决方法。希望该问题将在 springdoc-openapi 的下一版本中解决(在撰写本文时,当前版本为1.2.18)。
有关工作示例,请参见springdoc-security-override-fix