quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.79k stars 2.68k forks source link

No SecurityScheme on OpenAPI when using openIdConnect and @PermissionsAllowed #39227

Closed PierreAdam closed 8 months ago

PierreAdam commented 8 months ago

Describe the bug

I am building an API where I'm using quarkus-oidc to handle the authentication. The authentication is done by exchanging a JWT that contains a list of roles. Those roles are properly extracted and I can use @RolesAllowed to secure access to an endpoint. With @RolesAllowed the generated OpenAPI file is correct. I have the security scheme properly applied to the annotated endpoint.

In order to have more granularity in the API development / access, I started using the Permissions system. I defined the following configuration

quarkus.http.auth.permission.greetingApi.paths=/greeting/*
quarkus.http.auth.permission.greetingApi.policy=greeting-policy
quarkus.http.auth.policy.greeting-policy.roles-allowed=user
quarkus.http.auth.policy.greeting-policy.permissions.user=read

I then switched my endpoint from @RolesAllowed to @PermissionsAllowed. Then authentication part is working flawlessly. I'm able to use the permission system to validate access to the API.

    @GET
    @Path("test-read")
    @PermissionsAllowed("read")
    public String testMethod() { ... }

However then I noticed that the OpenAPI file generated was wrong. It no longer included the SecurityScheme that was used for the endpoint. This makes swagger-ui not working with the project.

I tried to add the security scheme explicitly on the endpoint by adding @SecurityScheme(ref = "SecurityScheme") but this seems ignored.

I cannot add an @Authenticated since @PermissionsAllowed is already there. So it seems to me that this part is not working as intended.

Expected behavior

---
openapi: 3.0.3
info:
  title: MyApp
  version: "1.0"
paths:
  /greeting/test-read:
    get:
      tags:
      - Greeting Controller
      parameters:
      - $ref: '#/components/parameters/Cashless-Contract'
      responses:
        "200":
          description: OK
          content:
            text/plain:
              schema:
                type: string
        "401":
          description: Not Authorized
        "403":
          description: Not Allowed
      security:
      - SecurityScheme:
        - admin
components:
  securitySchemes:
    SecurityScheme:
      type: openIdConnect
      description: Authentication
      openIdConnectUrl: https://my-sso.com/args

Actual behavior

---
openapi: 3.0.3
info:
  title: MyApp
  version: "1.0"
paths:
  /greeting/test-read:
    get:
      tags:
      - Greeting Controller
      parameters:
      - $ref: '#/components/parameters/Cashless-Contract'
      responses:
        "200":
          description: OK
          content:
            text/plain:
              schema:
                type: string
components:
  securitySchemes:
    SecurityScheme:
      type: openIdConnect
      description: Authentication
      openIdConnectUrl: https://my-sso.com/args

How to Reproduce?

  1. Set quarkus with an oidc authentication
  2. Set the permissions in the properties
  3. Add @PermissionsAllowed
  4. Call /q/openapi to see that your endpoint was not flagged as being secured.

Output of uname -a or ver

Windows

Output of java -version

OpenJDK 21

Quarkus version or git rev

3.8.1

Build tool (ie. output of mvnw --version or gradlew --version)

Maven 3.9.5

Additional information

The authentication and the permission system is as far as I'm aware working flawlessly. It's only /q/openapi that doesn't give the proper result.

quarkus-bot[bot] commented 8 months ago

/cc @EricWittmann (openapi), @MikeEdgar (openapi), @phillip-kruger (openapi), @sberyozkin (security)

phillip-kruger commented 8 months ago

@PierreAdam Thanks for the issue. Yes, at the moment the auto security filter only works on @RolesAllowed. (see https://github.com/quarkusio/quarkus/blob/main/extensions/smallrye-openapi/deployment/src/main/java/io/quarkus/smallrye/openapi/deployment/filter/AutoRolesAllowedFilter.java)

It should be possible to add the correct OpenAPI annotations as a workaround. Apart from the @SecurityScheme annotation on the class, you would need to add the @SecurityRequirement on the method you secure.

You are welcome to provide a PR to add support for @PermissionsAllowed in the filter, else I'll add that as soon as I have a gap.

PierreAdam commented 8 months ago

@phillip-kruger pull request was created thanks for pointing me in the right direction.