Swagger2 advanced: интеграция единой аутентификации и интерфейса входа SpringSecurity

Swagger

Swagger — это каноническая и полная платформа для создания, описания, вызова и визуализации веб-сервисов в стиле RESTful.

После того, как SpringBoot интегрирует Swagger, добавьте соответствующие аннотации на уровне контроллера для создания документов интерфейса, которые широко используются во внешних и внутренних проектах.

Единая сертификация

В конкретных проектах большая часть ресурсов защищена (ссылка:Spring Boot элегантно интегрирует Spring Security), то как установить глобальный токен входа на страницу Swagger? Swagger предоставляет абстрактный класс SecurityScheme специально для решения проблемы аутентификации, под ним есть три реализации, а именно:

  • ApiKey: поддерживает методы аутентификации как по заголовку, так и по запросу;
  • BasicAuth: простая аутентификация;
  • OAuth: метод аутентификации на основе OAuth2.

Сегодня мы в основном говорим об аутентификации заголовка ApiKey, которая заключается в добавлении токена учетных данных для входа в заголовок всех запросов на странице Swagger.

Интеграция стартера, предоставленного Сообществом Spring4all

<!-- swagger2 -->
<dependency>
  <groupId>com.spring4all</groupId>
  <artifactId>swagger-spring-boot-starter</artifactId>
  <version>1.9.1.RELEASE</version>
</dependency>

Настройте в файле конфигурации:

# swagger配置
swagger:
  # 是否开启swagger
  enabled: true
  title: Gits_接口文档
  # 全局统一鉴权配置
  authorization:
    key-name: GitsSessionID

Это добавит ключ в заголовок запроса какGitsSessionIDтокен, запуск проекта, доступip:port/swagger-ui.html

image
Нажмите кнопку «Авторизовать» в левом нижнем углу, установите токен, и вы можете с радостью использовать swagger.
image

Добавить интерфейс входа SpringSecurity на страницу Swagger

В некоторых сценариях нам нужно вручную добавить интерфейсы в Swagger, например: аннотации, отличные от SpringMVC, предоставляют интерфейсы (например, определенные в фильтрах), и документы интерфейса API не могут быть созданы с помощью этого метода аннотации.

В фильтре перехватывается интерфейс входа в систему с именем пользователя и паролем SpringSecurity. Вы можете просмотреть предыдущую статью:Анализ исходного кода входа в систему Spring Security (с блок-схемой).

Поэтому в Swagger нельзя увидеть интерфейс входа в систему, что очень неудобно при обычной разработке и тестировании.Нам нужно получить доступ к интерфейсу входа в инструмент postman для получения токена, а затем вернуться на страницу Swagger, чтобы установить токен , как прямой стальной человек , я просто хочу выполнить такую ​​​​операцию только на странице Swagger, что мне делать?

Путем реализации плагина, предоставленного swaggerApiListingScannerPlugin, вы можете вручную добавить интерфейс в документ swagger.

Попробуем добавить интерфейс входа SpringSecurity в swagger:

/**
 * 手动添加swagger接口,如登录接口等
 *
 * @author songyinyin
 * @date 2020/6/17 下午 10:03
 */
@Component
public class SwaggerAddtion implements ApiListingScannerPlugin {
    /**
     * Implement this method to manually add ApiDescriptions
     * 实现此方法可手动添加ApiDescriptions
     *
     * @param context - Documentation context that can be used infer documentation context
     * @return List of {@link ApiDescription}
     * @see ApiDescription
     */
    @Override
    public List<ApiDescription> apply(DocumentationContext context) {
        Operation usernamePasswordOperation = new OperationBuilder(new CachingOperationNameGenerator())
            .method(HttpMethod.POST)
            .summary("用户名密码登录")
            .notes("username/password登录")
            .consumes(Sets.newHashSet(MediaType.APPLICATION_FORM_URLENCODED_VALUE)) // 接收参数格式
            .produces(Sets.newHashSet(MediaType.APPLICATION_JSON_VALUE)) // 返回参数格式
            .tags(Sets.newHashSet("登录"))
            .parameters(Arrays.asList(
                new ParameterBuilder()
                    .description("用户名")
                    .type(new TypeResolver().resolve(String.class))
                    .name("username")
                    .defaultValue("admin")
                    .parameterType("query")
                    .parameterAccess("access")
                    .required(true)
                    .modelRef(new ModelRef("string"))
                    .build(),
                new ParameterBuilder()
                    .description("密码")
                    .type(new TypeResolver().resolve(String.class))
                    .name("password")
                    .defaultValue("123456")
                    .parameterType("query")
                    .parameterAccess("access")
                    .required(true)
                    .modelRef(new ModelRef("string"))
                    .build(),
                new ParameterBuilder()
                    .description("验证码唯一标识")
                    .type(new TypeResolver().resolve(String.class))
                    .name("randomKey")
                    .defaultValue("666666")
                    .parameterType("query")
                    .parameterAccess("access")
                    .required(true)
                    .modelRef(new ModelRef("string"))
                    .build(),
                new ParameterBuilder()
                    .description("验证码")
                    .type(new TypeResolver().resolve(String.class))
                    .name("code")
                    .parameterType("query")
                    .parameterAccess("access")
                    .required(true)
                    .modelRef(new ModelRef("string"))
                    .build()
            ))
            .responseMessages(Collections.singleton(
                new ResponseMessageBuilder().code(200).message("请求成功")
                    .responseModel(new ModelRef(
                        "xyz.gits.boot.common.core.response.RestResponse")
                    ).build()))
            .build();

        ApiDescription loginApiDescription = new ApiDescription("login", "/login", "登录接口",
            Arrays.asList(usernamePasswordOperation), false);

        return Arrays.asList(loginApiDescription);
    }

    /**
     * 是否使用此插件
     * 
     * @param documentationType swagger文档类型
     * @return true 启用
     */
    @Override
    public boolean supports(DocumentationType documentationType) {
        return DocumentationType.SWAGGER_2.equals(documentationType);
    }
}

Код немного длинный, небольшое пояснение.supportsМетод заключается в том, использовать ли этот плагин,applyМетод может вручную добавить ApiDescription, возвращаемым значением будет коллекция ApiDescription, а ApiDescription может быть создан с помощью шаблона построителя. Сначала создайте операцию для входа в систему с именем пользователя и паролем, в которой укажите метод запроса (method), теги (tags), параметры (parameters), возвращаемый результат (responseMessages) и т. д. Наконец, используйте построенный usernamePasswordOperation, путь запроса, описание запроса и т. д., чтобы создать ApiDescription для возврата.

Таким образом, вы можете увидеть только что определенный интерфейс на странице swagger.

image
Таким образом достигается логин-аутентификация-доступ к защищенным ресурсам Все три шага выполняются в чванстве, что красиво.

Дисплей достижений

  1. получить код подтверждения

image

  1. Войдите, чтобы получить токен

image

  1. унифицированная аутентификация

image

  1. Доступ к защищенным ресурсам

image
Этот раздел завершает унифицированную аутентификацию Swagger и интегрирует интерфейс входа в систему безопасности, что значительно облегчает обычную разработку и тестирование.


Герой медленный, оригинальным быть не просто, просто ставь лайк и вперед. Подпишитесь на официальный аккаунт и сможете заниматься проституцией бесплатно😘, в следующий раз не будьте уверены, только в этот раз🤣