springdoc-openapi是否可以应用默认的全局SecurityScheme?

时间:2019-12-16 13:03:24

标签: java spring swagger openapi springdoc

对于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注释?

如果是,如何将排除项添加到不安全的路径中?

2 个答案:

答案 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