oapi-codegen icon indicating copy to clipboard operation
oapi-codegen copied to clipboard

securitySchemes/bearerAuth usage unclear.

Open utx0 opened this issue 5 years ago • 7 comments

Hey guys,

I have been using this package for some time on a number of public API with great joy. However, I now have a need to set up JWT Bearer token auth on a number of API endpoints and I am finding that the usage patterns for this arent clear from reading the documentation or the code. I would really love some guidance on how this is meant to be implemented.

As a starting point I have defined the following test api endpoint in my openapi.json spec as follows;

components:
  responses:
    UnauthorizedError:
      description: Acces token is missing or invalid
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
paths:
  "/v1/jwt":
    get:
      security:
        - bearerAuth: []
      operationId: GetJWT
      summary: Get JWT info
      description: JWT Test interface
      responses:
        "200":
          description: Return info on the JWT
        "401":
          $ref: '#/components/responses/UnauthorizedError'

In turn, this generated the following in the codegen (Which for the life of me I can't see how this really archives anything useful?):

// GetJWT converts echo context to params.
func (w *ServerInterfaceWrapper) GetJWT(ctx echo.Context) error {
	var err error

	ctx.Set("bearerAuth.Scopes", []string{""})

	// Invoke the callback with all the unmarshalled arguments
	err = w.Handler.GetJWT(ctx)
	return err
}

Be great to know what is now required to turn a simple handler (as follows) into one that requires AUTH?

func (h *Handlers) GetDocs(ctx echo.Context) error {
	return ctx.File("public/rest/v1/api.html")
}

utx0 avatar Apr 28 '20 03:04 utx0

Why is the code []string{""} and not []string{} for empty list?

mitar avatar May 22 '21 08:05 mitar

So I made this work by making a custom middleware which validates the access token and checks that it has all the required scopes. And I get required scopes in the context from the code generated by this package.

mitar avatar May 25 '21 19:05 mitar

@mitar that's a good workaround I found myself using, but.. if we want to use OapiRequestValidator as in the examples no matter what we do the call will always fail

zeako avatar Jul 05 '21 14:07 zeako

So I made this work by making a custom middleware which validates the access token and checks that it has all the required scopes. And I get required scopes in the context from the code generated by this package.

Can you please guide on this more .. I am trying to write my own middleware, but i cannot find the scopes that are set. please see #911

debuggerpk avatar Dec 31 '22 19:12 debuggerpk

My middleware is just a wrapper around a handler.

mitar avatar Dec 31 '22 20:12 mitar

correct me if i am wrong, but wouldn't that require writing your own template for code generation? ..

right now, the code that is being generated is

func (w *ServerInterfaceWrapper) ValidateAPIKey(ctx echo.Context) error {
	var err error

	ctx.Set(APIKeyAuthScopes, []string{""})

	// Invoke the callback with all the unmarshalled arguments
	err = w.Handler.ValidateAPIKey(ctx)
	return err
}

we want the ServerInterfaceWrapper to be

type ServerInterfaceWrapper struct {
	Handler    ServerInterface
	Middleware echo.MiddlewareFunc
}

and the actual function to generate

func (w *ServerInterfaceWrapper) ValidateAPIKey(ctx echo.Context) error {
	var err error

	ctx.Set(APIKeyAuthScopes, []string{""})

	// Invoke the callback with all the unmarshalled arguments
	err = w.Middleware(w.Handler.ValidateAPIKey(ctx))
	return err
}

Thanks for taking a peak.

debuggerpk avatar Dec 31 '22 21:12 debuggerpk

I am using Chi. There, generated code looks like:

	ctx = context.WithValue(ctx, AccessTokenScopes, []string{"foobar"})

	var handler = func(w http.ResponseWriter, r *http.Request) {
		siw.Handler.GetFoobar(w, r)
	}

	for _, middleware := range siw.HandlerMiddlewares {
		handler = middleware(handler)
	}

	handler(w, r.WithContext(ctx))

So middlewares are called after context is set.

mitar avatar Dec 31 '22 22:12 mitar