swagger-api / swagger-api/swagger-codegen-generators

DefaultCodeGen is too aggressive in assuming Basic authentication

Open
#113 4 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Mustache
Stars
299
Forks
439
PR merge metrics
No merged PRs in 30d

Description

Hello!

I believe I have found a bug in DefaultCodegen. I would like to use HTTP authentication using the "Bearer" authentication scheme, like the Swagger Docs suggest I have the following OpenAPI security scheme declaration:

components:
  securitySchemes:
    bearer:
      type: http
      scheme: bearer

What I expect is that the generated client should set a corresponding HTTP header:

Authorization: Bearer <USER_PROVIDED_TOKEN_HERE>

However, the generated client initializes HTTP authentication that requires username and password, which are then encoded together. This prevents users from specifying their token in a natural way. The output in my case (Java) looks as follows:

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

Note that setUsername as well as setPassword do not make sense in my use-case and that setApiKey, setApiKeyPrefix, and setAccessToken will throw RuntimeExceptions because no authentication of the respective type is configured.

I think that the mistake lies in the two lines in DefaultCodegen that I have highlighted above. This code checks whether HTTP authentication should be used, and then, independently of the authentication scheme to be used, sets a flag that will trigger generation of basic authentication. This results in code incompatible with bearer authentication. For more background on HTTP authentication schemes, please refer to this article on MDN.

To fix this bug, I believe that a more granular treatment of HTTP authentication is needed. One branch should go for basic authentication as is done now always, but at least one more branch to forward credentials for other schemes is required. This could be done by adding another implementation of io.swagger.client.auth.Authentication or modifying io.swagger.client.auth.ApiKeyAuth slightly to account for HTTP authentication schemes, similar to setApiKeyPrefix.

I could implement the described fix, once you give your OK.

As a workaround, one may use:

components:
  securitySchemes:
    # Workaround for https://github.com/swagger-api/swagger-codegen-generators/issues/113
    bearer:
      type: apiKey
      in: header
      name: Authorization

In conjunction with some adjustments in the user code, for the Java case:

client.setApiKeyPrefix("Bearer");
client.setApiKey("<USER_PROVIDED_TOKEN_HERE>");

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in DefaultCodegenConfig.java at the authentication handling around lines 2508-2509, then inspect v2/Java/ApiClient.mustache around lines 102-108 and the Authentication and ApiKeyAuth implementations. Reproduce generation from the bearer security scheme shown in the issue; done means the generated Java client supports the Bearer token flow without requiring username/password or throwing for the relevant setters.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.