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. Я прочитал документацию которая дала мне некоторый намек на возможность использования базового auth. На этом этапе я должен упомянуть, что, с моей точки зрения, погашение очень плохое. В нем говорится:

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

Прежде всего, я хочу передать строку, как в заголовке http, но это не работает, и даже googling, как использовать базовый auth с swagger cli, не приводит к некоторому ясному answser. После многих попыток и ошибок я (я использую 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-клиент должен также использовать базовый auth. Я взглянул на методы из ApiClient и нашел setUsername и setPassword. Я думал, что эти методы позволяют клиенту использовать базовый auth, но не повезло.

Итак, я более подробно рассмотрел созданные классы, особенно 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);

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

1) закомментируйте аутентификации строк Collections.unmodifiableMap(аутентификации), чтобы хэш файл снова изменялся.

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

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

Ответ 1

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

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

Что вам нужно сделать: 1. Настройте определения безопасности. Вот простое базовое определение HTTP-аутентификации:

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

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

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

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

Ответ 2

Это так близко к правильности, но все еще не дает пример того, что вы на самом деле должны делать, чтобы использовать клиент. Я пытаюсь:

  SessionsApi apiAuth = GenClientHelper.getClientAuthSession();
  apiAuth.getApiClient().setUsername(config.user);
  apiAuth.getApiClient().setPassword(config.pass);
  Session session = apiAuth.createSession(); 

И это дает мне ошибку, говоря, что "для доступа к этому ресурсу требуются учетные данные". Где документация, которая говорит мне, как клиент будет использоваться?

Я с ОП. Здесь так много отличного, но совершенно не хватает основ.