0

I have a Quarkus endpoint stood up. Secured by JWT and Roles.

It works in Postman. (Header <Authorization, Bearer ey……>)

I have looked and struggled and found I can’t do a typical @Header or @Parameter annotation exposing this Authorization header—it stomps out that precise value. “Authorization1” I can expose. But not “Authorization”.

I have got a jwt configuration option in the application.YML file. I now get an authentication “padlock” on the UI but whatever I enter there doesn’t get passed to the CURL command in “try it out” mode.

Has anyone solved this problem?

application.yml parts:

  smallrye-openapi:
      ...
      jwt-bearer-format: JWT
      jwt-security-scheme-value: Bearer
      security-scheme: jwt

These images may be useful:

Postman--success SmallRye OpenAPI UI Auth SmallRye OpenAPI UI Auth header not being attached

Chris
  • 158
  • 3
  • 10
  • Looking at your images, you are attempting to invoke the `/test/roles-allowed` endpoint from within Swagger? And when attempting to do so, you are getting a 401 error. Yes? – allkenang Jul 11 '21 at 03:11
  • That’s right. This endpoint works in Postman with a JWT, so I know the service is working and that I’m issuing correct JWTs (also verified via JWT.io). The endpoint is not working in Swagger UI as it’s not passing -H “Authentication: Bearer ey…” through to the curl command. It smells like a bug to me. – Chris Jul 11 '21 at 08:43

1 Answers1

2

It's not really a bug. There is a configuration that you can specify in Quarkus that allows you to inject the JWT token into each request from Swagger.

There is some work that you need to do in order to accomplish this simply because Swagger will not know beforehand how to read the JWT token and how to reuse it for subsequent calls.

Below is one method that you can use in order to make Swagger calls work in a Quarkus project.

There are a few things to unpack here.

Caveat

This has been tested to work with Quarkus 2.0.1.Final. Older versions of Quarkus use an old version of SmallRye that has a bug in it when rendering the request interceptor.

  1. Use this configuration in Quarkus quarkus.swagger-ui.request-interceptor to inject the jwt token into the request headers of Swagger. This value goes into your application.properties. (Do modify this configuration to suit yml files)

quarkus.swagger-ui.request-interceptor=function(req){var authToken=sessionStorage.getItem('authenticationToken');if(authToken){req.headers['Authorization']='Bearer '+authToken;}return req;}

  1. Now go to your Swagger UI and login using the login endpoint that you use. This will return the jwt token. Go to the browser and input the value into your browser's Session Storage under the key 'authenticationToken'

  2. Now when you hit any endpoint that you want to test, Swagger will use the request interceptor (defined in 1) to inject the JWT from your browser's session storage and your calls will work.

allkenang
  • 1,511
  • 15
  • 12
  • That’s wild! I’m not sure I’ve ever seen a function call in Spring Boot Land properties files before (I’m very new to Quarkus). Apparently, there is a different/preferred way to do it; I was missing the annotation `@SecurityRequirement(name = "SecurityScheme")` before the secured endpoint. – Chris Jul 12 '21 at 16:17
  • oh nice! Didn't know that was possible and it looks much easier and cleaner. Thanks! – allkenang Jul 12 '21 at 22:41
  • See the bug report I opened, complete with public repro code, here: https://github.com/quarkusio/quarkus/issues/18614 As for “how does it work,” it’ll pick up on that annotation. I’ve pulled the main project—it’s HUGE—and I missed it on a quick once-over, but it’s got to be in the processor, right? – Chris Jul 13 '21 at 09:38
  • Also works with Keycloak using `function(req){var keycloakstring=localStorage.getItem('authorized');if(keycloakstring){ var keycloak = JSON.parse(keycloakstring) req.headers['Authorization']='Bearer '+.Keycloak.token.access_token;}}return req;} ` as value – markus May 13 '22 at 09:25