【问题标题】:Enable Authorize button in springdoc-openapi-ui for Bearer Token Authentication (JWT)在 springdoc-openapi-ui 中为承载令牌身份验证(JWT)启用授权按钮
【发布时间】:2020-05-10 22:11:05
【问题描述】:

如何在springdoc-openapi-ui (OpenAPI 3.0 /swagger-ui.html) 中启用“授权”按钮以进行不记名令牌身份验证,例如 JWT。

Spring @Controller@Configuration 类必须添加哪些注解?

【问题讨论】:

    标签: java spring jwt openapi springdoc


    【解决方案1】:

    如果您想避免在 @RestController 中使用 security 属性注释每个 @Operation,您可以在类级别添加它,从而影响控制器的每个操作。

    请不要忘记您的配置 bean 需要与其他示例中的相同:

    @Configuration
    @OpenAPIDefinition(info = @Info(title = "My API", version = "v1"))
    @SecurityScheme(
        name = "bearerAuth",
        type = SecuritySchemeType.HTTP,
        bearerFormat = "JWT",
        scheme = "bearer"
    )
    public class OpenApi30Config {
    }
    

    在类级别添加安全要求

    您只需在那些您想限制 API 调用的类上使用 @SecurityRequirement(name = "bearerAuth")。请注意,这些注释是继承的,因此您也可以将它们添加到任何界面。

    创建一个带有所需注解的标记界面:

    @SecurityRequirement(name = "bearerAuth")
    public interface SecuredRestController {
    }
    

    将标记接口添加到您希望将限制应用于所有操作的那些控制器,例如:

    @RestController
    @RequestMapping("/hello")
    public class HelloController implements SecuredController {
    
        @GetMapping
        public String hello() {
            return "Hello World";
        }
    
        @GetMapping("/{name}")
        public String helloWithName(@PathVariable String name) {
            return "Hello " + name;
        }
    
    }
    

    你可以在没有标记界面的情况下这样做:

    @RestController
    @RequestMapping("/hello")
    @SecurityRequirement(name = "bearerAuth")
    public class HelloController {
    ...
    }
    

    现在您的操作都受到保护并需要 JWT 令牌。

    在方法级别添加安全要求

    正如在另一篇文章中所说,您必须将@SecurityRequirement 添加到您的方法的@Operation 注释中。

    @RestController
    @RequestMapping("/hello")
    public class HelloController {
    
        @GetMapping
        @Operation(summary = "My endpoint", security = @SecurityRequirement(name = "bearerAuth"))
        public String hello() {
            return "Hello World";
        }
    
        @GetMapping("/{name}")
        public String helloWithName(@PathVariable String name) {
            return "Hello " + name;
        }
    
    }
    

    这仅限制第一个操作,而不限制第二个操作。

    【讨论】:

    • 谢谢,你帮了我!但是,如果您将文本“请不要忘记...”而不是在答案的 开头 处输入,我将不胜感激,这样可以节省我一小时的调试时间:) 我对“在方法级别添加安全要求”不感兴趣,所以我不再在那里阅读您的答案:)
    【解决方案2】:

    我更喜欢使用 bean 初始化而不是注解。

    import io.swagger.v3.oas.models.Components;
    import io.swagger.v3.oas.models.OpenAPI;
    import io.swagger.v3.oas.models.info.Info; 
    import io.swagger.v3.oas.models.security.SecurityRequirement; 
    import io.swagger.v3.oas.models.security.SecurityScheme;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.util.StringUtils;
    
    @Configuration
    public class OpenApi30Config {
    
      private final String moduleName;
      private final String apiVersion;
    
      public OpenApi30Config(
          @Value("${module-name}") String moduleName,
          @Value("${api-version}") String apiVersion) {
        this.moduleName = moduleName;
        this.apiVersion = apiVersion;
      }
    
      @Bean
      public OpenAPI customOpenAPI() {
        final String securitySchemeName = "bearerAuth";
        final String apiTitle = String.format("%s API", StringUtils.capitalize(moduleName));
        return new OpenAPI()
            .addSecurityItem(new SecurityRequirement().addList(securitySchemeName))
            .components(
                new Components()
                    .addSecuritySchemes(securitySchemeName,
                        new SecurityScheme()
                            .name(securitySchemeName)
                            .type(SecurityScheme.Type.HTTP)
                            .scheme("bearer")
                            .bearerFormat("JWT")
                    )
            )
            .info(new Info().title(apiTitle).version(apiVersion));
      }
    }
    

    代码行

    .addSecurityItem(new SecurityRequirement().addList(securitySchemeName))
    

    允许添加全局安全模式并摆脱对每个 @Operation 的写入安全性 方法。

    【讨论】:

    • 这可行,但无法与注释一起使用。当我使用注释时,授权按钮不会显示,但我可能错过了某事。在那里。
    • 很好的解决方案,可以避免每个 @Operation 方法的安全性。
    • 导入 io.swagger.v3.oas.models.Components;导入 io.swagger.v3.oas.models.OpenAPI;导入 io.swagger.v3.oas.models.info.Info;导入 io.swagger.v3.oas.models.security.SecurityRequirement;导入 io.swagger.v3.oas.models.security.SecurityScheme;导入 org.springframework.beans.factory.annotation.Value;导入 org.springframework.context.annotation.Bean;导入 org.springframework.context.annotation.Configuration;导入 org.springframework.util.StringUtils; ---- 添加导入命令,因为有几个模棱两可的选项
    • 如果你做全局安全模式,你如何告诉swagger一个特定的端点是开放的,不应该被标记为privete?
    • @JenkaBY 为什么在构造函数中使用“@Value”注解?而是避免多写 5 行,正确放入属性?
    【解决方案3】:

    使用 @Configuration bean 中的注释 @io.swagger.v3.oas.annotations.security.SecurityScheme 为 OpenAPI 3.0 定义全局安全方案:

    @Configuration
    @OpenAPIDefinition(info = @Info(title = "My API", version = "v1"))
    @SecurityScheme(
        name = "bearerAuth",
        type = SecuritySchemeType.HTTP,
        bearerFormat = "JWT",
        scheme = "bearer"
    )
    public class OpenApi30Config {
    
    }
    

    使用 @io.swagger.v3.oas.annotations.Operation 引用定义的安全方案来注释每个需要承载令牌身份验证 (JWT) 的 @RestController 方法:

    @Operation(summary = "My endpoint", security = @SecurityRequirement(name = "bearerAuth"))
    

    【讨论】:

    • 我也在试验这个。我以为在授权对话框中添加不记名令牌后,swagger 会自动将其添加到所有后续请求的标头中.. 但似乎没有
    猜你喜欢
    • 2020-05-10
    • 2021-03-01
    • 2018-07-01
    • 1970-01-01
    • 2018-01-20
    • 2017-12-10
    • 1970-01-01
    • 2019-05-22
    • 2021-10-27
    相关资源
    最近更新 更多