Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OIDC authentication using Flask-pyoidc. #1492

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

openbrian
Copy link

Here's a PR to add OIDC authentication. It works just fine with Keycloak.

It does not fit into your design pattern because your Moin assumes all authentication methods have a password. OIDC does not. It will NOT login the user in middleware.

Initially there's support for 1 identity provider, but with small changes you can add multiple IDPs.

This change was very hard to make given the architecture of the current system. I left comments where Moin can become a more idiomatic Flask website. Notably:

  • getting the user from the session should not depend on the authentication mode
  • authentication should happen in a view/controller, not middleware
  • the session needs only 2 items: user id, session_token
  • model classes should not be touching the session
  • the indexer is a pain in the ass to use / it should return objects not dictionaries

These are noted in the codebase with my initials: BCD. Feel free to ignore and delete them.

A web app should not be inventing it's own authentication and session management. Consider using Flask-Login to handle this. (Also consider using Flask-Security-Too.)

@RogerHaase
Copy link
Member

RogerHaase commented Aug 30, 2023

setup.py:111:17: E999 SyntaxError: invalid syntax

Also had to uncomment these lines in wikiconfig.py:

OIDC_REDIRECT_URI = 'http://localhost:5000/oidc_redirect_uri'
OIDC_ISSUER="https://localhost:8080/auth/realms/myfolks"
OIDC_CLIENT_ID='example.com/wiki'  # best practice is to use domain name and path here
OIDC_CLIENT_SECRET='get this from the idp administrator'
OIDC_LOGOUT_URI='todo'

After setting sso = True in wikiconfig.py:

(moin-venv-python) C:\AA-GIT\BrianD\moin>m run --port 8080
2023-08-31 09:55:24,714 ERROR oic.oauth2.base:138 http_request failed: HTTPSConnectionPool(host='localhost', port=8080):
 Max retries exceeded with url: /auth/realms/myfolks/.well-known/openid-configuration (Caused by NewConnectionError('<ur
llib3.connection.HTTPSConnection object at 0x00000213C9EA69E0>: Failed to establish a new connection: [WinError 10061] N
o connection could be made because the target machine actively refused it')), url: https://localhost:8080/auth/realms/my
folks/.well-known/openid-configuration, htargs: {'allow_redirects': True, 'cert': None, 'verify': True, 'timeout': 5.0},
 method: GET
Traceback (most recent call last):
  File "\\?\C:\AA-GIT\BrianD\moin-venv-python\Scripts\moin-script.py", line 33, in <module>
    sys.exit(load_entry_point('moin', 'console_scripts', 'moin')())
  File "C:\AA-GIT\BrianD\moin-venv-python\lib\site-packages\click\core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
  File "C:\AA-GIT\BrianD\moin-venv-python\lib\site-packages\click\core.py", line 1078, in main
    rv = self.invoke(ctx)
  File "C:\AA-GIT\BrianD\moin-venv-python\lib\site-packages\click\core.py", line 1688, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "C:\AA-GIT\BrianD\moin-venv-python\lib\site-packages\click\core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "C:\AA-GIT\BrianD\moin-venv-python\lib\site-packages\click\core.py", line 783, in invoke
    return __callback(*args, **kwargs)
  File "C:\AA-GIT\BrianD\moin-venv-python\lib\site-packages\click\decorators.py", line 92, in new_func
    return ctx.invoke(f, obj, *args, **kwargs)
  File "C:\AA-GIT\BrianD\moin-venv-python\lib\site-packages\click\core.py", line 783, in invoke
    return __callback(*args, **kwargs)
  File "C:\AA-GIT\BrianD\moin-venv-python\lib\site-packages\flask\cli.py", line 911, in run_command
    raise e from None
  File "C:\AA-GIT\BrianD\moin-venv-python\lib\site-packages\flask\cli.py", line 897, in run_command
    app = info.load_app()
  File "C:\AA-GIT\BrianD\moin-venv-python\lib\site-packages\flask\cli.py", line 301, in load_app
    app = self.create_app()
  File "c:\aa-git\briand\moin\src\moin\app.py", line 52, in create_app
    return create_app_ext(flask_config_file=config)
  File "c:\aa-git\briand\moin\src\moin\app.py", line 158, in create_app_ext
    oidc.init_app(app)
  File "C:\AA-GIT\BrianD\moin-venv-python\lib\site-packages\flask_pyoidc\flask_pyoidc.py", line 86, in init_app
    self.clients = {
  File "C:\AA-GIT\BrianD\moin-venv-python\lib\site-packages\flask_pyoidc\flask_pyoidc.py", line 87, in <dictcomp>
    name: PyoidcFacade(configuration, self._redirect_uri_config.full_uri)
  File "C:\AA-GIT\BrianD\moin-venv-python\lib\site-packages\flask_pyoidc\pyoidc_facade.py", line 41, in __init__
    provider_metadata = provider_configuration.ensure_provider_metadata(self._client)
  File "C:\AA-GIT\BrianD\moin-venv-python\lib\site-packages\flask_pyoidc\provider_configuration.py", line 179, in ensure
_provider_metadata
    resp = client.provider_config(self._issuer)
  File "C:\AA-GIT\BrianD\moin-venv-python\lib\site-packages\oic\oauth2\__init__.py", line 1150, in provider_config
    r = self.http_request(url, allow_redirects=True)
  File "C:\AA-GIT\BrianD\moin-venv-python\lib\site-packages\oic\oauth2\base.py", line 135, in http_request
    req.request(method, url, **_kwargs),
  File "C:\AA-GIT\BrianD\moin-venv-python\lib\site-packages\requests\sessions.py", line 589, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\AA-GIT\BrianD\moin-venv-python\lib\site-packages\requests\sessions.py", line 703, in send
    r = adapter.send(request, **kwargs)
  File "C:\AA-GIT\BrianD\moin-venv-python\lib\site-packages\requests\adapters.py", line 519, in send
    raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPSConnectionPool(host='localhost', port=8080): Max retries exceeded with url: /a
uth/realms/myfolks/.well-known/openid-configuration (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection o
bject at 0x00000213C9EA69E0>: Failed to establish a new connection: [WinError 10061] No connection could be made because
 the target machine actively refused it'))

@openbrian
Copy link
Author

Start up an open ID connect server on port 8080. I suggest keycloak. Create a realm. Add a user, set a password. Create a client, set a client id. Set the redirect uri that matches your env.

@openbrian
Copy link
Author

Or use a commercial one like Okta or Auth0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants