Skip to content

How to support OAuth2 Password flows? #562

Open

Description

@jmg-duarte

Question

I'm currently developing an API that makes use of OAuth2 Password Flows and need to be able to authenticate to use it.

Currently, there is no OAuth2 specific code, but for my use case, merely allowing me to declare the Authorization header would already solve my issue. However, there is no way (that I know of) of declaring arbitrary headers on the generated code.

I'm already modifying my OpenAPI schema to handle #558 (comment) but would appreciate more escape hatches on the Swift side.

To that end, I am keen on helping implementing the generation for either the escape hatch or the Authorization header on the presence of OAuth security schemes. Just tell me where to look into!

Activity

  1. added
    kind/supportAdopter support requests.
    status/triageCollecting information required to triage the issue.
    on Apr 5, 2024
  2. czechboy0 commented on Apr 5, 2024

    @czechboy0
    Contributor

    Hi @jmg-duarte,

    you're right that there is no special code generated for OAuth2 flows yet, that's a missing feature: https://swiftpackageindex.com/apple/swift-openapi-generator/1.2.1/documentation/swift-openapi-generator/supported-openapi-features#OAuth-Flows-Object

    In the short term, we recommend folks implement a ServerMiddleware and add any auth information as a task local, as shown in this example: https://github.com/apple/swift-openapi-generator/tree/main/Examples/auth-server-middleware-example

    Long term, it'd be great to see a proposal of how to better support OAuth2 in the generated code. I don't think we've come up with a design yet, and we welcome the community proposing one (using our Proposal process).

  3. jmg-duarte commented on Apr 5, 2024

    @jmg-duarte
    Author

    In the short term, we recommend folks implement a ServerMiddleware and add any auth information as a task local, as shown in this example: https://github.com/apple/swift-openapi-generator/tree/main/Examples/auth-server-middleware-example

    I'm doing a client though, would that work?

  4. czechboy0 commented on Apr 5, 2024

    @czechboy0
    Contributor

    developing an API

    Apologies, I took the above to mean you're writing the server. Yes, just replace ServerMiddleware with ClientMiddleware, and use this example instead: https://github.com/apple/swift-openapi-generator/tree/main/Examples/auth-client-middleware-example

  5. czechboy0 commented on Oct 29, 2024

    @czechboy0
    Contributor

    Related to #37.

  6. added this to the Post-1.0 milestone on Oct 29, 2024
  7. laconicman commented on Apr 7, 2025

    @laconicman

    I'm currently developing an API that makes use of OAuth2 Password Flows and need to be able to authenticate to use it.
    To that end, I am keen on helping implementing the generation for either the escape hatch or the Authorization header on the presence of OAuth security schemes. Just tell me where to look into!

    Perhaps this piece of code modesty named RefreshTokenAuthMiddleware might be useful to you. It's not OAuth2, but it's a refresh token authentication scenario. You might be able to reuse some of the approaches.
    I'm no expert on Modern Concurrency, but I've tried to make use of it.

  8. huven commented on Jun 25, 2025

    @huven

    Is it supported to call next() more than once inside intercept()?

    If the server responds with 401, the middleware can obtain a new access token using the refresh token, and then retry the request before returning the response, all without bothering the caller. I'd rather not wrap all API calls with that logic.

    I know the client could do that periodically before expiration and pass the new token to the middleware, but there might be other reasons for the server to return 401.

    This could be used for resiliency too.

  9. czechboy0 commented on Jun 25, 2025

    @czechboy0
    Contributor

    Yes in a middleware, it's allowed to call next() multiple times, exactly for this use case, like retries.

    The only time when it won't work is if you're doing request streaming using a single-iteration HTTPBody. But otherwise will work.

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

    kind/supportAdopter support requests.status/triageCollecting information required to triage the issue.

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions