connexion
connexion copied to clipboard
Swagger UI's oauth authorization has wrong redirect address
Description
When I use the Swagger UI to get authorization from an Oauth server, the request includes a redirect location of http://localhost:3200/oauth2-redirect.html
(the default redirect url of swagger ui), which is not accessible, as the connexion app I am running do not share the same host/port (I am using localhost:8080).
Expected Behaviour
I expect connexion to change the redirect url setting of swagger ui to a relative path adjusting to the actual running app.
Version
I am on connexion 2.2.0
I have a similar issue, trying to access the swagger ui on production.
Found a workaround though -- by changing the Swagger UI is served from to /, the redirect works as expected, as now the oauth2-redirect.html
is in the right place:
my_app = connexion.App(
__name__,
specification_dir=...,
options={
'swagger_url': '/',
})
Of course that makes only sense if you don't have other things to serve from /
.
The redirect page is actually available as /ui/oauth2-redirect.html
- it's just that it needs to send an absolute URL for the redirect and is unaware it needs to add the ui/
. This is something that you can configure in the swagger-ui, but I'm still trying to find out if we can actually pass configuration options to the swagger UI via connexion.
Yes, you can do this:
options = {
"swagger_ui_config": {
"oauth2RedirectUrl": "localhost:8080/ui/oauth2-redirect.html"
}
}
app = connexion.FlaskApp(__name__, specification_dir='openapi/', options=options)
But it looks like you have to pass an absolute URL, which means you can't use flask to generate it with the correct server name
This is definitely something that connexion should handle.
Thanks @SpoonMeiser - this saved me a lot of time - and thanks for posting a clear solution.
As I'm also using a base path I need to add this to the URL. So if my hostname is example.com
, and I'm using a base-path of /data
and a swagger URL of /api
then the redirect URL becomes https://example.com/data/api/oauth2-redirect.html
. I have these values in a Config
module so my connexion options are setup like this...
# Option configuration for connexion/flask
#
# Set the oauth2 redirect URL.
# If we're using path-based API (i.e. hosted anywhere other than '/')
# or a swagger API not on this PATH then we need to provide an oauth2
# redirect URL that includes the base path and swagger path.
# See problem and solution posted at
# https://github.com/zalando/connexion/issues/968
#
# Here, for our deployment,
# API_HOSTNAME is typically 'example.com'
# API_BASE_PATH is typically '/data'
# SWAGGER_PATH is typically '/api'
_OAUTH2_REDIRECT_URL: str =\
'https://%s%s%s/oauth2-redirect.html' % (Config.API_HOSTNAME,
Config.API_BASE_PATH,
Config.SWAGGER_PATH)
CONNEXION_OPTIONS: dict = {'swagger_url': Config.SWAGGER_PATH,
'swagger_ui_config': {
'oauth2RedirectUrl': _OAUTH2_REDIRECT_URL}}
# Start the Connexion app,
# identifying the base directory for the OpenAPI definition...
connexion_app = connexion.FlaskApp(__name__,
specification_dir='openapi/',
options=CONNEXION_OPTIONS)
...but, yes, it would be really handy of connexion could figure his out for itself!
I'm using connexion[swagger-ui] == 2.7.0
Wouldn't redirecting with something like this by default workaround the problem?
@app.route('/oauth2-redirect.html')
def oauth2_redirect():
args = "&".join(var + "=" + value for var, value in request.args.items())
return redirect('/api/ui/oauth2-redirect.html?' + args, 302)
It seems to be a pretty simple workaround while the root cause is not tackled. It also doesn't need to know the current hostname to work.
Would there be any security concerns caused by doing it this way?
Neat - but I'm also a Pod in a Kubernetes cluster and my Ingress directs all traffic at /data
(in my case) to my Pod. All traffic on the base path (/
) on the other hand goes to another Pod (another application in my cluster) as directed by a different Ingress.
I have a multiple applications served from the same hostname (example.com
) so I cannot expect /oauth2-redirect.html
to be sent to my application - it'll go to different application.