Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide first-class (generated) code to support authentication/authorization #1524

Open
jamietanna opened this issue Mar 29, 2024 · 3 comments
Labels
enhancement New feature or request

Comments

@jamietanna
Copy link
Member

As part of #1254 I'm looking at documenting the way that securitySchemes works, and it turns out it's a little more lackluster than I remember.

Right now, if you define an endpoint i.e.:

  /apiKey:
    get:
      operationId: apiKey
      description: Perform an authenticated request, using an API Key in the `X-API-Key` header
      security:
        - apiKey: []
      responses:
      # ... snip 

This generates only the following code:

@@ -20,7 +20,6 @@ import (
 )
 
 const (
+       ApiKeyScopes    = "apiKey.Scopes"
        BasicAuthScopes = "basicAuth.Scopes"
 )
 
@@ -55,8 +54,6 @@ type MiddlewareFunc func(http.Handler) http.Handler
 func (siw *ServerInterfaceWrapper) ApiKey(w http.ResponseWriter, r *http.Request) {
        ctx := r.Context()
 
+       ctx = context.WithValue(ctx, ApiKeyScopes, []string{})
+
        handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                siw.Handler.ApiKey(w, r)
        }))

This still requires a lot of work to hand-roll server-side authentication.

We should instead generate

We can generated ??, and then rely on an implemented method sfor

multi reoutes

k
Although it can be possible to use the middleware to authenticate, I believe it's an area we can improve on.

We'll need to consider:

  • the existence of the middleware(s) to not re-authenticate
  • the existence of multiple means to authenticate - is it first one wins?

This should be opt-in.

Example schema:

Some code can be found in 09adbb0

See also:

#843
#177
#221
#911

@jamietanna jamietanna added the enhancement New feature or request label Mar 29, 2024
@alehed
Copy link

alehed commented Jun 6, 2024

The current approach sort of works if you restrict yourself to one security scheme per endpoint. We are currently using a middleware which checks the request against the given authenticators. Using it looks something like this:

serverOptions := demo.ChiServerOptions{
	...
	Middlewares: []demo.MiddlewareFunc{
		OAPICodegenAuthMiddleware(map[string]Authenticator{
			api.ApiKeyScopes:    ApiKeyAuthenticator(db),
			api.BasicAuthScopes: BasicAuthenticator(usernamePasswordHashes),
		})},
}

@alehed
Copy link

alehed commented Jun 6, 2024

For the issue with multiple security schemes per endpoint see #1644.

Our middleware currently resolves this problem by always assuming OR (which is the more common case) and disallowing AND-ing security schemes, but that has other drawbacks.

@mromaszewicz
Copy link
Member

IMO, putting anything to do with auth scopes into the generated code was a mistake, because it's a runtime behavior handled properly by openapi3filter. I have an API running at my workplace which has a complex specification with multiple schemes and it works ok.

I think we should deprecate authentication logic from the generated code altogether, and I'm happy to clean up the middleware or example to make it clear how to do this. Our middleware was written when openapi3filter was quite more primitive, and we could use it better today.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants