aws-powertools / powertools-lambda-python

A developer toolkit to implement Serverless best practices and increase developer velocity.
https://docs.powertools.aws.dev/lambda/python/latest/
MIT No Attribution
2.86k stars 393 forks source link

Bug: swaggerUIRedirectOauth2 null after redirect #4427

Closed Thomas-McKanna closed 2 months ago

Thomas-McKanna commented 4 months ago

Expected Behaviour

Complete login flow to generate JWT access token.

Current Behaviour

When I click on "Authorize" button in Swagger UI, the login flow begins and I'm eventually redirected back to a URL like:

https://example.com/v3/swagger?format=oauth2-redirect&code=XXXXXXXX-6ee0-4b21-a78a-1a1d9652df68&state=XXXXXXXXXSAzMCAyMDI0IDE1OjE3OjA0IEdNVC0wNTAwIChDZW50cmFsIERheWxpZ2h0IFRpbWUp

But at this point, the flow fails with a blank page. The HTML for the page is the correct "Redirect" generated HTML, but there is an error in the console like:

TypeError: Cannot read properties of null (reading 'swaggerUIRedirectOauth2')
    at run (swagger?format=oauth2-redirect&code=XXXXXe0-4b21-a78a-1a1d9652df68&state=XXXXXCAyMDI0IDE1OjE3OjA0IEdNVC0wNTAwIChDZW50cmFsIERheWxpZ2h0IFRpbWUp:10:36)
    at HTMLDocument.<anonymous> (swagger?format=oauth2-redirect&code=XXXXX-6ee0-4b21-a78a-1a1d9652df68&state=XXXXXCAyMDI0IDE1OjE3OjA0IEdNVC0wNTAwIChDZW50cmFsIERheWxpZ2h0IFRpbWUp:74:13)

And it seems that no other Javascript is being loaded by the page.

Code snippet

oauth2 = OAuth2Config(
    client_id="CHANGEME",
    app_name="CHANGEME",
)

app = APIGatewayRestResolver(enable_validation=True)
app.enable_swagger(
    path="/swagger",
    oauth2_config=oauth2,
    security_schemes={
        "oauth": OAuth2(
            flows=OAuthFlows(
                authorizationCode=OAuthFlowAuthorizationCode(
                    authorizationUrl="https://CHANGEME/oauth2/authorize",
                    tokenUrl="https://CHANGEME/oauth2/token",
                ),
            ),
        ),
    },
    security=[{"oauth": []}],
)

Possible Solution

I wonder if the swagger_js generated for the main Swagger page is supposed to also be loaded in here, but is not because of the redirect flow resetting the web page (https://docs.powertools.aws.dev/lambda/python/latest/api/event_handler/openapi/swagger_ui/index.html).

Steps to Reproduce

Should be able to use the config I gave in the code snippet, assuming you have an oauth2 identity provider at hand.

Powertools for AWS Lambda (Python) version

latest

AWS Lambda function runtime

3.10

Packaging format used

PyPi

Debugging logs

No response

leandrodamascena commented 4 months ago

Hey @Thomas-McKanna! Thanks for opening this issue.

I suspect that somewhere in the authentication mechanism it is not possible to read the properties of the Swagger main page. Let me explain the steps we took to authenticate and recover the token, which may help us identify the problem.

1 - When we set up OAuth2 authentication in SwaggerUI, it opens a modal window to fill in the client/secret (I'm using machine-to-machine authentication, but the process is the same for user authentication). When we click on the Authorizer button, it takes us to a new OIDC provider tab and one parameter we send is the redirect URL, in my case this is http://localhost:3000/swagger?format=oauth2-redirect.

2 - When the authentication is successful and the OIDC Provider redirects to http://localhost:3000/swagger?format=oauth2-redirect, the first thing that happens is accessing the swaggerUIRedirectOauth2 object from the Swagger main page, and that's where the issue is occurring in your case. For some reason, it is not possible to read this object. I have tested this with Chrome, Firefox, Safari, as well as with Cognito, Keycloak, and Okta, and I was unable to reproduce the problem in any of these scenarios. This suggests that in your specific case, either a page is being reloaded and losing the reference to swaggerUIRedirectOauth2, or there is some other reason why it is not possible to read this object.

3 - If I directly access the page /swagger?format=oauth2-redirect without authentication, I encounter the same error as you, which further reinforces the idea that, for some reason, the page is might being reloaded in your scenario.

Maybe you can test a few more scenarios to see if you can find the source of the problem? I haven't made much progress in identifying this here on my side.

Thanks

Thomas-McKanna commented 4 months ago

Hmmmm. I have been looking into this one for a while and I can't seem to figure it out. For some reason, browser is setting window.opener to null. I've tried in Safari, Chrome, and Firefox. My best guess is that it that the problem is due to my OAuth2 origin being different than my Swagger origin (auth.example.com vs. myapp.example.com). Then again, I don't know how you would have gotten it working with localhost.

I'm using Cognito Hosted UI. I'm going to drop work on this one for now.

@leandrodamascena Do you think it makes sense to keep this issue open in case someone else has the same issue? Otherwise, I will close it.

leandrodamascena commented 4 months ago

Hi @Thomas-McKanna, I think we can have a call and if possible you can show me your scenario and I will try to reproduce it here. It is now 5PM here and I have until 6PM, if you can, we can talk for a few minutes and I can better understand the scenario you are in there. If you are having this problem, perhaps others are and we would like to get ahead of this.

If you prefer, we can schedule this meeting the next week.

Please send an email to aws-powertools-maintainers at amazon.com and I'll provide you with a chime link.

heitorlessa commented 4 months ago

(for my own on-call update).. this call happened. We might be able to get it released this Thursday, otherwise later this month

leandrodamascena commented 2 months ago

Hello @Thomas-McKanna! I tried my best to find a way to solve this problem, but there's nothing we can do about it here. The problem is that we really need the opener's reference (the window/tab who opened the window/tab auth) to update SwaggerUI, without that there's nothing we can do.

I'm closing this issue, but if you find a solution and/or we find one on our side, we can open it again.

Thanks for insights and your patience.

github-actions[bot] commented 2 months ago

⚠️COMMENT VISIBILITY WARNING⚠️

This issue is now closed. Please be mindful that future comments are hard for our team to see.

If you need more assistance, please either tag a team member or open a new issue that references this one.

If you wish to keep having a conversation with other community members under this issue feel free to do so.