diff --git a/README.md b/README.md index adb7848..39601ae 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,8 @@ config = ProviderConfiguration([provider configuration], client_metadata=client_ **Note: The redirect URIs registered with the provider MUST include `/redirect_uri`, where `` is the URL of the Flask application.** +To configure this extension to use a different endpoint, set the +[`OIDC_REDIRECT_ENDPOINT` configuration parameter](#flask-configuration). #### Dynamic client registration @@ -91,6 +93,8 @@ You may also configure the way the user sessions created by this extension are h * `OIDC_SESSION_PERMANENT`: If set to `True` (which is the default) the user session will be kept until the configured session lifetime (see below). If set to `False` the session will be deleted when the user closes the browser. +* `OIDC_REDIRECT_ENDPOINT`: Set the endpoint used as redirect_uri to receive authentication responses. Defaults to + `redirect_uri`, meaning the URL `/redirect_uri` needs to be registered with the provider(s). * `PERMANENT_SESSION_LIFETIME`: Control how long a user session is valid, see [Flask documentation](http://flask.pocoo.org/docs/1.0/config/#PERMANENT_SESSION_LIFETIME) for more information. diff --git a/src/flask_pyoidc/flask_pyoidc.py b/src/flask_pyoidc/flask_pyoidc.py index 79816d2..132ddc6 100644 --- a/src/flask_pyoidc/flask_pyoidc.py +++ b/src/flask_pyoidc/flask_pyoidc.py @@ -36,13 +36,12 @@ except ImportError: from urlparse import parse_qsl + class OIDCAuthentication(object): """ OIDCAuthentication object for Flask extension. """ - REDIRECT_URI_ENDPOINT = 'redirect_uri' - def __init__(self, provider_configurations, app=None): """ Args: @@ -55,21 +54,24 @@ def __init__(self, provider_configurations, app=None): self.clients = None self._logout_view = None self._error_view = None + self._redirect_uri_endpoint = None if app: self.init_app(app) def init_app(self, app): + self._redirect_uri_endpoint = app.config.get('OIDC_REDIRECT_ENDPOINT', 'redirect_uri').lstrip('/') + # setup redirect_uri as a flask route - app.add_url_rule('/redirect_uri', - self.REDIRECT_URI_ENDPOINT, + app.add_url_rule('/' + self._redirect_uri_endpoint, + self._redirect_uri_endpoint, self._handle_authentication_response, methods=['GET', 'POST']) # dynamically add the Flask redirect uri to the client info with app.app_context(): self.clients = { - name: PyoidcFacade(configuration, url_for(self.REDIRECT_URI_ENDPOINT)) + name: PyoidcFacade(configuration, url_for(self._redirect_uri_endpoint)) for (name, configuration) in self._provider_configurations.items() } @@ -161,7 +163,7 @@ def _handle_error_response(self, error_response, should_redirect=False): # if the current request was from the JS page handling fragment encoded responses we need to return # a URL for the error page to redirect to flask.session['error'] = error_response - return '/redirect_uri?error=1' + return '/' + self._redirect_uri_endpoint + '?error=1' return self._show_error_response(error_response) def _show_error_response(self, error_response): diff --git a/tests/test_flask_pyoidc.py b/tests/test_flask_pyoidc.py index 78cde1a..a2eca3a 100644 --- a/tests/test_flask_pyoidc.py +++ b/tests/test_flask_pyoidc.py @@ -468,3 +468,9 @@ def test_using_unknown_provider_name_should_raise_exception(self): with pytest.raises(ValueError) as exc_info: self.init_app().oidc_auth('unknown') assert 'unknown' in str(exc_info.value) + + def test_should_use_custom_redirect_endpoint(self): + self.app.config['OIDC_REDIRECT_ENDPOINT'] = '/openid_connect_login' + authn = self.init_app() + assert authn._redirect_uri_endpoint == 'openid_connect_login' + assert authn.clients['test_provider']._redirect_uri == 'http://client.example.com/openid_connect_login'