OpenAPITools / OpenAPITools/openapi-generator

[BUG] [Java] `Authentication undefined: my-auth-name` in ApiClient.java

Open
#19,168 9 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Issue: Bug
Dominant language
Java
Stars
26.8k
Forks
7.7k
PR merge metrics
PR metrics pending

Description

Bug Report Checklist
  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator (example)?
  • Have you tested with the latest master to confirm the issue still exists? I omitted this since the suspected pieces of code have not changed for a while, including recently.
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description and Reproduction

Given an OpenAPI with a security schema of type openIdConnect, e.g.:

{
  "openapi" : "3.0.3",
  "info" : {
    "title" : "My API",
    "version" : "1.0.0"
  },
  "security" : [ {
    "Keycloak" : [ ]
  } ],
  "paths" : {
    "/api/stuff" : {
      "post" : {
        "summary" : "Does something important.",
        "responses" : {
          "200" : {
            "description" : "Everything went well"
          }
        },
        "security" : [ {
          "Keycloak" : [ "api_access" ]
        } ]
      }
    }
  },
  "components" : {
    "securitySchemes" : {
      "Keycloak" : {
        "type" : "openIdConnect",
        "description" : "This service is secured through OIDC, implemented by Keycloak",
        "openIdConnectUrl" : "https://auth.example.com/realms/myrealm/.well-known/openid-configuration"
      }
    }
  }
}

and a generated Java client, e.g. through the openapi-generator maven plugin in a spring boot project:

<plugin>
    <groupId>org.openapitools</groupId>
    <artifactId>openapi-generator-maven-plugin</artifactId>
    <version>7.7.0</version>
    <executions>
        <execution>
            <id>generate-my-client</id>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <inputSpec>${project.build.directory}/my-openapi.json</inputSpec>
                <generatorName>java</generatorName>
                <library>webclient</library>
                <invokerPackage>com.example.myclient.invoker</invokerPackage>
                <apiPackage>com.example.myclient.api</apiPackage>
                <modelPackage>com.example.myclient.model</modelPackage>

                <configOptions>
                    <openApiNullable>false</openApiNullable>
                    <sourceFolder>myapi</sourceFolder>
                    <useSpringBoot3>true</useSpringBoot3>
                    <useJakartaEe>true</useJakartaEe>
                </configOptions>
            </configuration>
        </execution>
    </executions>
</plugin>

invocation fails with the following error:

org.springframework.web.client.RestClientException: Authentication undefined: Keycloak
	at com.example.myclient.invoker.ApiClient.updateParamsForAuth(ApiClient.java:701)
	at com.example.myclient.invoker.ApiClient.prepareRequest(ApiClient.java:622)
	at com.example.myclient.invoker.ApiClient.invokeAPI(ApiClient.java:582)
	at com.example.myclient.api.MergedApi.searchMarktrollenRequestCreation(MergedApi.java:8023)
	at com.example.myclient.api.MergedApi.searchMarktrollen(MergedApi.java:8039)
	at com.example.MyService.doClientCall(MyService.java:XY)
	[...]

which is emitted from this generated code:

protected void updateParamsForAuth(String[] authNames, MultiValueMap<String, String> queryParams, HttpHeaders headerParams, MultiValueMap<String, String> cookieParams) {
    for (String authName : authNames) {
        Authentication auth = authentications.get(authName);
        if (auth == null) {
            throw new RestClientException("Authentication undefined: " + authName);
        }
        auth.applyToParams(queryParams, headerParams, cookieParams);
    }
}
openapi-generator version and Related issues/PRs

I tested 6.6.0, 7.5.0 and 7.7.0.
It worked with 6.5.0 and is "broken" since the initial OIDC support landed in 6.6.0: https://github.com/OpenAPITools/openapi-generator/pull/15417

Investigation and suggested fix

Previous to the initial OIDC support, source generation would just output the following error:

[ERROR] Unknown type `openIdConnect` found in the security definition `null`.

This also caused localVarAuthNames in api/MyApi.java to generate as follows:

String[] localVarAuthNames = new String[] {  };

Starting with 6.6.0, the above error is no longer emitted during generation, and instead this code is emitted:

String[] localVarAuthNames = new String[] { "Keycloak" };

In another generated file, the invoker/ApiClient.java, the init method is generated as follows for all versions I tested:

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

The respective mustache file ApiClient.mustache currently looks like this:

// Setup authentications (key: authentication name, value: authentication).
authentications = new HashMap<String, Authentication>();{{#authMethods}}{{#isBasic}}{{#isBasicBasic}}
authentications.put("{{name}}", new HttpBasicAuth());{{/isBasicBasic}}{{#isBasicBearer}}
authentications.put("{{name}}", new HttpBearerAuth("{{scheme}}"));{{/isBasicBearer}}{{/isBasic}}{{#isApiKey}}
authentications.put("{{name}}", new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}"));{{/isApiKey}}{{#isOAuth}}
authentications.put("{{name}}", new OAuth());{{/isOAuth}}{{/authMethods}}
// Prevent the authentications from being modified.
authentications = Collections.unmodifiableMap(authentications);

I believe there is a case for isOpenIdConnect missing in this template. I don't know how easily it could be added, or whether there needs to be some fallback mechanism for authentication mechanisms that are not supported by some code generators.

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 with modules/openapi-generator/src/main/resources/Java/ApiClient.mustache and the referenced Java webclient api.mustache template, then compare their generated output for an openIdConnect security scheme. Verify the generated client initializes the named authentication and no longer throws “Authentication undefined” when the API operation is invoked; check whether existing generator tests cover this path.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.