Skip to content

Commit

Permalink
Enable OAuth2 Implicit authentication round-trip (#585)
Browse files Browse the repository at this point in the history
The swagger-ui project contains a 'oauth2-redirect.html' file
which provides a credential trampoline. Vendor it in, and
place the external url to this file in swagger-ui.html.

The OAuth2 authentication loop is run in a popup window/tab.
The IDP will redirect back to the oauth2RedirectUrl with an
access_token provided in the #hash-fragment of the url.
Javascript running inside 'oauth2-redirect.html' pushes the
access_token back to the parent which created the window/tab,
before closing the tab.

Enables use-case in #544 without adding another config param.

Usage:

```python
app.config.SWAGGER_UI_OAUTH_CLIENT_ID = 'MyClientId'
app.config.SWAGGER_UI_OAUTH_REALM = '-'
app.config.SWAGGER_UI_OAUTH_APP_NAME = 'Demo'
api = Api(
    app,
    title='Demo',
    security={'OAuth2': ['read', 'write']},
    authorizations={
        'OAuth2': {
            'type': 'oauth2',
            'flow': 'implicit',
            'authorizationUrl': 'https://idp.example.com/authorize?audience=https://app.example.com',
            'clientId': app.config.SWAGGER_UI_OAUTH_CLIENT_ID,
            'scopes': {
                'openid': 'Get ID token',
                'profile': 'Get identity',
            }
        }
    }
)
```
  • Loading branch information
ellieayla authored and SteadBytes committed Aug 11, 2019
1 parent fe085c8 commit f5c1c27
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 1 deletion.
35 changes: 35 additions & 0 deletions doc/swagger.rst
Original file line number Diff line number Diff line change
Expand Up @@ -953,6 +953,41 @@ You can specify a custom validator URL by setting ``config.SWAGGER_VALIDATOR_URL
api = Api(app)
You can enable [OAuth2 Implicit Flow](https://oauth.net/2/grant-types/implicit/) for retrieving an
authorization token for testing api endpoints interactively within Swagger UI.
The ``config.SWAGGER_UI_OAUTH_CLIENT_ID`` and ``authorizationUrl`` and ``scopes``
will be specific to your OAuth2 IDP configuration.
The realm string is added as a query parameter to authorizationUrl and tokenUrl.
These values are all public knowledge. No *client secret* is specified here.
.. Using PKCE instead of Implicit Flow depends on https://github.com/swagger-api/swagger-ui/issues/5348
.. code-block:: python
from flask import Flask
app = Flask(__name__)
app.config.SWAGGER_UI_OAUTH_CLIENT_ID = 'MyClientId'
app.config.SWAGGER_UI_OAUTH_REALM = '-'
app.config.SWAGGER_UI_OAUTH_APP_NAME = 'Demo'
api = Api(
app,
title=app.config.SWAGGER_UI_OAUTH_APP_NAME,
security={'OAuth2': ['read', 'write']},
authorizations={
'OAuth2': {
'type': 'oauth2',
'flow': 'implicit',
'authorizationUrl': 'https://idp.example.com/authorize?audience=https://app.example.com',
'clientId': app.config.SWAGGER_UI_OAUTH_CLIENT_ID,
'scopes': {
'openid': 'Get ID token',
'profile': 'Get identity',
}
}
}
)
You can also specify the initial expansion state with the ``config.SWAGGER_UI_DOC_EXPANSION``
setting (``'none'``, ``'list'`` or ``'full'``):

Expand Down
3 changes: 3 additions & 0 deletions flask_restplus/templates/swagger-ui.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@
window.onload = function() {
const ui = window.ui = new SwaggerUIBundle({
url: "{{ specs_url }}",
{% if config.SWAGGER_UI_OAUTH_CLIENT_ID -%}
oauth2RedirectUrl: "{{ url_for('restplus_doc.static', filename='oauth2-redirect.html', _external=True) }}",
{%- endif %}
validatorUrl: "{{ config.SWAGGER_VALIDATOR_URL }}" || null,
dom_id: "#swagger-ui",
presets: [
Expand Down
2 changes: 1 addition & 1 deletion tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ def assets(ctx):
with ctx.cd(ROOT):
ctx.run('npm install')
ctx.run('mkdir -p flask_restplus/static')
ctx.run('cp node_modules/swagger-ui-dist/{swagger-ui*.{css,js}{,.map},favicon*.png} flask_restplus/static')
ctx.run('cp node_modules/swagger-ui-dist/{swagger-ui*.{css,js}{,.map},favicon*.png,oauth2-redirect.html} flask_restplus/static')
# Until next release we need to install droid sans separately
ctx.run('cp node_modules/typeface-droid-sans/index.css flask_restplus/static/droid-sans.css')
ctx.run('cp -R node_modules/typeface-droid-sans/files flask_restplus/static/')
Expand Down

0 comments on commit f5c1c27

Please sign in to comment.