GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Support multiple authentication schemes for a single endpoint · Issue #1644 · oapi-codegen/oapi-codegen

Support multiple authentication schemes for a single endpoint #1644

New issue
Copy link
New issue
Copy link
Closed as not planned
Closed as not planned
Support multiple authentication schemes for a single endpoint#1644
Copy link

Description

@alehed
alehed
opened on Jun 6, 2024
Issue body actions

The OpenAPI spec allows specifying multiple security schemes per endpoint/api.

Examples taken from https://swagger.io/docs/specification/authentication/:

Example 1:

security:    # A OR B
  - A
  - B

Example 2:

security:    # A AND B
  - A
    B

Example 3:

security:    # (A AND B) OR (C AND D)
  - A
    B
  - C
    D

Currently the generated server code for example 1 and 2 are identical, which means they cannot be differentiated from any middlewares.

Activity

  1. mromaszewicz commented on Jun 6, 2024

    @mromaszewicz
    mromaszewicz
    on Jun 6, 2024
    Member
    More actions

    I use oapi-codegen in this exact scenario, and this authentication logic doesn't need to go into the generated code, openapi3filter handles it just fine. It'll evaluate the boolean combination of auth schemes correctly, what you need to do is to provide a handler function to tell it whether each individual auth spec is correct.

    What kind of generated code do you think would help here?

  2. alehed commented on Jun 6, 2024

    @alehed
    alehed
    on Jun 6, 2024
    Author
    More actions

    Ideally the code generator would take care of this entirely, similarly like ogen does this with security handlers.

    Alternatively, the generator could add some information to the request context about which authentication methods need to pass, such that a middleware can do the actual authentication. Right now we are using a middleware that guesses this information based on the scopes info in the request context.

    I'm not super happy with using a separate tool that reads the api spec at runtime (this complicates deployment/testing).

  3. mromaszewicz commented on Jun 6, 2024

    @mromaszewicz
    mromaszewicz
    on Jun 6, 2024
    Member
    More actions

    The generator doesn't have enough context to make an authorization decision for you entirely, this will always be a runtime check for your own code, with the aid of generated code or middleware. What I'm trying to say is that this can be done completely generically in middleware. This is how we do it for many API's that take multiple OIDC and BasicAuth providers.

    At generation time, we don't know how you're going to validate each scheme, so that would have to be a callback for each kind, eg, A, B, C and D in your example, but then our generated code would entirely duplicate what the openapi3filter middleware does.

    Let me poke around a bit and see how we can make this nicer today.

  4. alehed commented on Jun 6, 2024

    @alehed
    alehed
    on Jun 6, 2024
    Author
    More actions

    I agree that it cannot be done without user-provided callbacks for A, B, C and D.

    Right now we have a generic custom middleware which takes callbacks and does the authentication. But due to limited information it has, it can only check A OR B OR C OR D (or it could check the arguably less useful A AND B AND C AND D).

    What our middleware does is basically:

    for scopeKey, callback := range authenticators {
        if r.Context().Value(scopeKey) != nil {
            // call callback to check auth and break if successful
        }
    }
    
    if !authenticated {
        // send back 401
    }
    
    next.ServeHTTP(w, r)

    So it checks for the scope keys in the context.

    What I meant about the runtime thing is that to use openapi3filter you need to keep the yaml file around and have it available to the server at runtime (and we need to make sure that we use the same file for generation as well as validation, etc..).

  5. alehed commented on Jun 6, 2024

    @alehed
    alehed
    on Jun 6, 2024
    Author
    More actions

    I just saw that you can use the EmbeddedSpec option to make this runtime loading of the spec potentially less painful.

    Reacted by Marcin Romaszewicz
  6. mromaszewicz commented on Jun 6, 2024

    @mromaszewicz
    mromaszewicz
    on Jun 6, 2024
    Member
    More actions

    Yeah, exactly. The embedded spec is 100% guaranteed to be in-sync with your code and middleware should use it. It never even occurred to me that people wouldn't set this option :)

  7. mromaszewicz commented on Jul 16, 2026

    @mromaszewicz
    mromaszewicz
    on Jul 16, 2026
    Member
    More actions

    We've deprecated embedding auth scope info into the request context, it's really a task for middleware to perform auth. Even the simple embedding we had was causing problems. It was a mistake to include any of this in the first place. We won't be expanding the codegen for auth, because the solution exists in validation middleware (and that's completely independent of any codegen, which is a good thing).

  8. mromaszewicz
    closed this as not plannedon Jul 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.