Включить кнопку авторизации в springdoc-openapi-ui для аутентификации токена-носителя (JWT)

Как включить кнопку «Авторизовать» в springdoc-openapi-ui (OpenAPI 3.0 /swagger-ui.html) для аутентификации токена-носителя, например JWT.

Какие аннотации нужно добавить к классам Spring @Controller и @Configuration?

Кнопка авторизации

«Форма


person Evgeniy Khyst    schedule 24.01.2020    source источник


Ответы (3)


Я предпочитаю использовать инициализацию 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 метода.

person JenkaBY    schedule 13.03.2020
comment
Это работает, но не работает с аннотациями. Кнопка авторизации не отображалась, когда я использовал аннотации, но я, вероятно, что-то пропустил. там. - person Stefan Haberl; 08.06.2020
comment
Хорошее решение, позволяющее избежать защиты каждого @Operation метода. - person SSK; 10.06.2020
comment
импортировать io.swagger.v3.oas.models.Components; импортировать 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; ---- добавить команду импорта, потому что есть несколько неоднозначных вариантов - person Mr Special; 08.11.2020
comment
Если вы создадите глобальную схему безопасности, как вы сообщите чванству, что конкретная конечная точка является открытой и не должна быть помечена как privete? - person Luke; 12.03.2021
comment
@JenkaBY, почему вы использовали аннотацию @Value внутри конструктора? Вместо того, чтобы избежать еще 5 строк, правильно указав атрибуты? - person rios0rios0; 06.04.2021
comment
@ rios0rios0 Вы правы. Нет причин аннотировать параметры конструктора с помощью @Value. Не стесняйтесь изменять и улучшать код. - person JenkaBY; 07.04.2021
comment
@JenkaBY Мне очень жаль, но я не могу. StackOverflow выдает мне сообщение об ошибке: очередь редактирования в настоящий момент заполнена - попробуйте еще раз через несколько минут !. Я пробовал один час. Вы можете редактировать, пожалуйста? - person rios0rios0; 07.04.2021
comment
Все ли операции используют определенную конфигурацию bean-компонента по умолчанию? Потому что даже если я не использую @SecurityRequirement (name = some name), определенная авторизация все равно добавляется в мои операции API. Так что меня это беспокоит. Мне нужно их добавлять или нет? Если у меня один тип авторизации. Я полагаю, это имеет смысл, когда у вас есть несколько способов авторизации, изменит ли это сгенерированные операции API? - person cvetan; 09.05.2021

Определите глобальную схему безопасности для OpenAPI 3.0, используя аннотацию @io.swagger.v3.oas.annotations.security.SecurityScheme в @Configuration bean-компоненте:

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

}

Аннотируйте каждый @RestController метод, требующий аутентификации токена-носителя (JWT) с @io.swagger.v3.oas.annotations.Operation ссылкой на определенную схему безопасности:

@Operation(summary = "My endpoint", security = @SecurityRequirement(name = "bearerAuth"))
person Evgeniy Khyst    schedule 24.01.2020

Если вы хотите избежать аннотирования каждого @Operation внутри вашего @RestController атрибутом security, вы можете добавить его на уровне класса, влияя на каждую операцию вашего контроллера.

Добавление требований безопасности на уровне класса

Все, что вам нужно сделать, это просто использовать @SecurityRequirement(name = "bearerAuth") в тех классах, для которых вы хотите ограничить вызовы API. Обратите внимание, что эти аннотации унаследованы, поэтому вы также можете добавить их в любой интерфейс.

Создайте интерфейс маркера с необходимой аннотацией:

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

}

Это ограничивает только первую операцию, но не вторую. введите описание изображения здесь

Не забывайте, что ваш компонент конфигурации должен быть таким же, как в другом примере:

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