Swagger Codegen CLI Java Client - как использовать его правильно

в настоящее время я играю с моим сервисом отдыха jersey2. Для лучшего обзора данной услуги (описание, типы и т. д.) Я сильно использую swagger (swagger-jersey2-jaxrs). Таким образом, я могу генерировать свое описание службы (swagger.json), и я могу просматривать и исследовать их через Swagger ui.

теперь я нахожусь в том, что мне нужно создать некоторых клиентов, чтобы использовать эти услуги. Я пришел accrooss swagger codegen cli, который является хорошим инструментом для создания вашего клиента и много разных языков (java в моем случае). Я могу создать клиент api и используемую модель.

здесь я подошел к первой проблеме. Службы REST и описание swagger являются http basic auth protected. Я прочитал документация что дало мне некоторый намек на то, что есть возможность использовать basic auth. В этот момент я должен упомянуть, что с моей точки зрения doucmentation очень плохое. Он говорит:

- a, --auth добавляет заголовки авторизации при удаленном извлечении определений swagger. Передайте строку name:header в кодировке URL с запятой, разделяющей несколько значений.

Первое, что я thoght, это передать строку, как в HTTP-заголовке, но это не работает, и даже поиск в гугле, как использовать basic auth с swagger cli, не привел к некоторому четкому ответчику. После многих попыток и ошибок я (я использую CLI 2.1.2), я, наконец, пришел к правильному формату, например:

java-jar swagger-codegen-cli-2.1.2.jar generate - a "авторизация: базовая YWRtaW46YWRtaW4=" - i http://localhost:8080/webproject/restapi/swagger.в JSON - L java-o restclient

где YWRtaW46YWRtaW4= - это значение, закодированное в base64 admin: admin в моем случае.

пока все хорошо. Сгенерированный клиент java также должен использовать базовую аутентификацию. Я взглянул на методы из ApiClient и нашел setUsername и setPassword. Я думал, что это методы empoweres клиенту использовать базовую аутентификацию, но не повезло.

поэтому я более подробно рассмотрел сгенерированные классы, особенно ApiClient и несколько сгенерированных классов ApiService. Я обнаружил, что setUsername и setPassword не имеют никакого эффекта из-за следующего:

/**
   * Helper method to set username for the first HTTP basic authentication.
   */
  public void setUsername(String username) {
    for (Authentication auth : authentications.values()) {
      if (auth instanceof HttpBasicAuth) {
        ((HttpBasicAuth) auth).setUsername(username);
        return;
      }
    }
    throw new RuntimeException("No HTTP basic authentication configured!");
  }

где в то же время HashMap определяется следующим образом:

// Setup authentications (key: authentication name, value: authentication).
authentications = new HashMap<String, Authentication>();
// Prevent the authentications from being modified.
authentications = Collections.unmodifiableMap(authentications);

аутентификация hashmap становится неизменяемой, но почему? Что является целью? Кроме того нет вспомогательные методы внутри ApiClinet, который генерирует необходимый объект auth, поэтому я сделал следующее:

1) прокомментируйте коллекции аутентификаций строк.unmodifiableMap (аутентификации), поэтому hashmap снова становится модифицируемым

2) Создайте необходимый объект auth вручную

HttpBasicAuth authentication = new HttpBasicAuth(); 
authentication.setUsername("admin");
authentication.setPassword("admin");

3) Добавьте объект auth в HashMap аутентификации apiClients:

ApiClient apiClient = new ApiClient();
apiClient.setBasePath(basePath);
apiClient.getAuthentications().put("basic", authentication);

4) изменение метода invokeApi (ApiClient.java)

public String invokeAPI(String path, String method, Map<String, String> queryParams, Object body, Map<String, String> headerParams, Map<String, String> formParams, String accept, String contentType, String[] authNames) throws ApiException {
String authNames2[] = {"basic"};
updateParamsForAuth(authNames2, queryParams, headerParams);
//updateParamsForAuth(authNames, queryParams, headerParams);
...

Шаг 4 необходимо, потому что ApiServices вызывают метод apiClient следующим образом:

String[] authNames = new String[] {  };
String response = apiClient.invokeAPI(path, "POST", queryParams, postBody, headerParams, formParams, accept, contentType, authNames);

другим возможным решением было бы определить ключ для проверки подлинности hashmap в каждом apiService, например:

String[] authNames = new String[] { "basic" };

после выполнения всех изменений, все работает как надо, но я не могу думать, что это идея автоматически REST-клиента. Поэтому мой вопрос: я пропустил какой-то момент или я должен думать о клиенте, сгенерированном swagger (java в этот случай) больше бета-решения, которое находится в разработке? Пожалуйста, поймите меня правильно, я думаю, что вся структура swagger (поддержка jersey2, openapi, swaggerui, codegen) - отличная вещь, и я ценю усилия разработчиков, но я хочу использовать codegen правильно, и я не думаю, что идея позади так должна настроить сгенерированные ApiClient и ApiServices таким образом.

1 ответов


проблема в том, что в вашей спецификации не упоминаются типы безопасности, которые вы хотите использовать (a.к. a. Определения безопасности) или какое определение безопасности применяется к какой конечной точке.

спецификация swagger является здесь, но это не рассказать всю историю.

что вам нужно сделать, это 1. Настройте определения безопасности. Вот простое базовое определение http auth:

securityDefinitions:
  basic:
    type: basic
    description: HTTP Basic Authentication. 

и 2. Используйте это определение безопасности в конце точка.

paths:
  /:
    get:
      security:
       - basic: []
      responses:
        200:
          description:  OK

затем восстановите свой клиентский код swagger. Он должен правильно настроить неизменяемую карту и массив authNames.