当前位置: 首页 > 知识库问答 >
问题:

springdoc openapi是否可以应用默认全局安全方案?

党权
2023-03-14

我使用springdoc openapi for java SpringBoot RESTful应用程序定义了以下SecurityScheme

    @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"));
    }

是否可以将其全局应用于所有路径,而不必在代码中的任何地方添加@SecurityRequirement注释到@Operation注释?

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

共有2个答案

邵阳
2023-03-14

使用springdoc-openapi的v1.2.29进行测试:使用@Security要求可以禁用特定endpoint的安全性

@GetMapping("/open")
@ResponseBody
@SecurityRequirements
public String open() {
    return "It works!";
}

对于较旧的版本,例如,使用v1测试。2.28使用OperationCustomizer:

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;
    };
}
侯池暝
2023-03-14

是的,您可以在同一位置调用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")));
  }

全局安全架构可以被另一个带有@SecurityRequirements注释的架构覆盖。包括删除操作的安全架构。例如,我们可以删除注册路径的安全性。

@SecurityRequirements
@PostMapping("/registration")
public ResponseEntity post(@RequestBody @Valid Registration: registration) {
    return registrationService.register(registration);
}

同时仍然保留其他API的安全模式。

旧答案(19年12月20日):

全局安全架构可以被另一个带有@SecurityRequirements注释的架构覆盖。但对于不安全的路径,无法将其删除。它在springdoc openapi中偶然缺少功能,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());
    }
}

现在,我们可以将@Tag(name=SecurityOverrideCustomizer.UNSECURED)添加到不安全的方法中:

    @Tag(name = SecurityOverrideCustomizer.UNSECURED)
    @GetMapping("/open")
    @ResponseBody
    public String open() {
        return "It works!";
    }

请记住,这只是一个解决办法。希望这个问题能在下一个springdoc openapi版本中得到解决(在编写时,当前版本是1.2.18)。

有关工作示例,请参见springdoc安全覆盖修复程序

 类似资料:
  • 设置全局默认样式,将会影响所有写入单元格的样式; 函数原型 defaultFormat(resource $formatHandler) resource $formatHandler $config = ['path' => './tests']; $excel = new \Vtiful\Kernel\Excel($config); ​ $excel->fileName('tutorial

  • 问题内容: Python 3.4。尝试在urllib.request.urlopen()中查找默认超时是多少。 它的签名是:urllib.request.urlopen(URL,data = None,[timeout,] *,cafile = None,capath = None,cadefault = False,context = None) 该文档称其为“全局默认超时”,并查看其代码:so

  • 所以,我一直在读C++标准,找到了[defns.Undefined](3.27,在我正在读的C++17草案中,请注意,当我在这里引用C++17时,我在其他标准中发现了类似的措辞)--这是未定义行为的定义。我注意到这样的措辞(强调我的): 注意:当本国际标准省略任何行为的明确定义时,或者当程序使用错误的构造或错误的数据时,可能会出现未定义的行为 现在,想想看,这有点道理。这有点像是说,如果标准没有给

  • 首先让我说,“记录器”是指任何一类负责向用户或程序员报告诊断或进度信息的对象。根据这个定义,“记录器”将包括图形用户界面上的反馈,如进度条。 我们一再被告知要避免全局状态,尤其是全局可变状态(GMS)。因为伐木者天生是可变的,所以我最近试图让我的伐木者“不是全球性的”。我尝试了各种策略(比如通过构造函数向记录器注入引用)。我终于意识到,所有的方法都是把口红贴在猪身上。 日志记录器必须是所有类(或至

  • 我一直在思考jvm安全的工作方式。原则是,jvm始终信任并运行任何本地代码。因此,从概念上讲,如果您的代码没有显式或隐式调用<code>checkpermission(permission)</code>,这意味着它永远不会失败任何安全验证。当然,所有这些验证调用通常都是在JavaAPI类中完成的,因此我们不需要为内置权限调用它们。 现在,只要您使用内置类(如<code>FileOutputStr

  • 问题内容: mysql_real_rescape_string()是否足以保护我免受黑客和SQL攻击?问问是因为我听说这些方法不能帮助您抵御所有攻击媒介?寻求专家的建议。 编辑:此外,怎么样的SQL攻击? 问题答案: @查尔斯是非常正确的! 您面临多种 已知 SQL攻击的风险,包括您提到的 SQL注入:是的!Mysql_Escape_String可能仍然使您容易受到SQL注入的影响,具体取决于您在