zamzterz/Flask-pyoidc

Silently refreshing tokens fails at redirect with empty UserSession

Closed this issue · 2 comments

We're using Flask-pyoidc to protect our API-Endpoints and SwaggerUI from unwanted accesses.
What currently happens, when session_refresh_interval_seconds is set, is that API requests using SwaggerUI fail when running into the refresh interval timeout.

What happens is that, when issuing a request to the API endpoint using Swagger/Flasgger, the request is redirected to our IDP and redirected back to our service's redirect_uri.
When this redirect back to us happens (first an OPTIONS request, assuming it's a preflight, which then turns into a GET) it is without data in the UserSession, resulting in Trying to pick-up uninitialised session without specifying 'provider_name' in _handle_authentication_response.

To work around this currently one has to switch to a different tab and loading the SwaggerUI there again to refresh the token.

I haven't tested this with a SwaggerUI-implementation, so I don't fully understand why it works by loading it in a different tab? Is there some minimal example you could provide to reproduce?

In general though, if no cookies are passed with the request it will unfortunately fail. The session cookie is associated with necessary internal Flask-pyoidc state.

The reason is you don't decorate swagger-ui view function with OIDC and you can't because swagger-ui is provided by the 3rd party package. What you should do is document the authorization of your APIs for Swagger. Swagger-ui has its own authorization implemented and it will obtain the access token from IdP independent of Falsk-pyoidc. You also have to register redirect URI of Swagger in your IdP's client settings.

This is how to document authorization of your APIs for Swagger.

authorizations = {
    'oauth2': {
        'type': 'oauth2',
        'flow': 'accessCode',  # authorizationCode in OpenAPI 3.0
        # 'flow': 'application',  # clientCredentials in OpenAPI 3.0
        # 'flow': 'implicit',
        'authorizationUrl': 'https://idp.example.com/auth,
        'tokenUrl': 'https://idp.example.com/token,
        'clientId': 'client_id123',
        'scopes': {
            'openid': 'Get ID token',
        }
    }
}

Swagger sends access token in the request header so make sure your views are decorated with either @auth.token_auth or @auth.access_control. @auth.oidc_auth is only meant to be used for browser-agents, not for the rest API clients.

@zamzterz You can mark this issue as closed. v3.10 fixed this issue with swagger.