Skip to main content

OIDC support for Plone sites

Project description

pas.plugins.oidc logo

pas.plugins.oidc

PyPI PyPI - Python Version PyPI - Wheel PyPI - License PyPI - Status

PyPI - Plone Versions

Meta Code Style

GitHub contributors GitHub Repo stars

Intro

This is a Plone authentication plugin for OpenID Connect. OAuth 2.0 should work as well because OpenID Connect is built on top of this protocol.

Features

  • PAS plugin, although currently no interfaces are activated.
  • Three browser views for this PAS plugin, which are the main interaction with the outside world.

Group Enumeration

If you need to support group enumeration from a Keycloak server, we recommend installing the package [pas.plugins.keycloakgroups](https://pypi-hypernode.com/project/pas.plugins.keycloakgroups/).

Installation

This package supports Plone sites using Volto and ClassicUI.

For proper Volto support, the requirements are:

  • plone.restapi >= 8.34.0
  • Volto >= 16.10.0

Add pas.plugins.oidc to the Plone installation using pip:

bash pip install pas.plugins.oidc

Requirements

As of version 2.* of this package the minimum requirements are Plone 6.0 and python 3.8.

Warning

Pay attention to the customization of User info property used as userid field, with the wrong configuration it's easy to impersonate another user.

Configure the plugin

  • Go to the Add-ons control panel and install pas.plugins.oidc.
  • In the ZMI go to the plugin properties at http://localhost:8080/Plone/acl_users/oidc/manage_propertiesForm
  • Configure the properties with the data obtained from your provider:
    • OIDC/Oauth2 Issuer
    • Client ID
    • Client secret
    • redirect_uris: this needs to match the public URL where the user will be redirected after the login flow is completed. It needs to include the /Plone/acl_users/oidc/callback part. When using Volto you need to expose Plone somehow to have the login process finish correctly.
    • Use Zope session data manager: see the section below about the usage of session.
    • Create user / update user properties: when selected the user data in Plone will be updated with the data coming from the OIDC provider.
    • Create authentication __ac ticket: when selected the user will be allowed to act as a logged-in user in Plone.
    • Create authentication auth_token (Volto/REST API) ticket: when selected the user will be allowed to act as a logged-in user in the Volto frontend.
    • Open ID scopes to request to the server: information requested to the OIDC provider. Leave it as it is or modify it according to your provider's information.
    • Use PKCE: when enabled uses PKCE when requesting authentication from the provider.

Login and Logout URLs

Default UI (Volto)

When using this plugin with a Volto frontend, please install @plone-collective/volto-authomatic add-on on your frontend project.

  • Login URL: <Path to your Plone site>/login
  • Logout URL: <Path to your Plone site>/logout

Also, on the OpenID provider, configure the Redirect URL as <Path to your Plone site>/login-oidc/oidc.

Classic UI

When using this plugin with Plone 6 Classic UI the standard URLs used for login (http://localhost:8080/Plone/login) and logout (http://localhost:8080/Plone/logout) will not trigger the usage of the plugin.

To login into a site using the OIDC provider, you will need to change those login URLs to the following:

  • Login URL: /<Plone Site Id>/acl_users/<oidc pas plugin id>/login
  • Logout URL: /<Plone Site Id>/acl_users/<oidc pas plugin id>/logout

Where:

  • Plone Site Id: is the id you gave to the Plone site when you created it. It is usually Plone but may vary. It is the last part of the URL when you browse Plone directly without using any proxy server, ex. http://localhost:8080/Plone+ -> Plone.

  • oidc pas plugin id: is the id you gave to the OIDC plugin when you created it inside the Plone PAS administration panel. If you just used the default configuration and installed this plugin using Plone's Add-on Control Panel, this id will be oidc.

Example setup with Keycloak

The pas.plugins.oidc repository has a working setup for a Keycloak development server using Docker and Docker Compose. To use it, in a terminal, run the command:

Start-up

make keycloak-start

This does not give you a production setup, but it is fine for local development.

This command will use the docker-compose.yml file available in the tests directory.

Manage Keycloak

After start up, Keycloak will be accessible on http://127.0.0.1:8180, and you can manage it with the following credentials:

  • username: admin
  • password: admin

Realms

There are two realms configured plone and plone-test. The later is used in automated tests, while the former should be used for your development environment.

The plone realm ships with an user that has the following credentials:

  • username: user
  • password: 12345678

And, to configure the oidc plugins, please use:

  • client id: plone
  • client secret: 12345678

Stop Keycloak

To stop a running Keycloak (needed when running tests), use:

make keycloak-stop

Warning

Attention, before Keycloak 18, the parameter for logout was redirect_uri and it has been deprecated since version 18. But the Keycloak server can run with the redirect_uri if needed, it is possible to use the plugin with the legacy redirect_uri parameter enabled also. The problem is that if the deprecated parameter is enabled in the plugin but not in the server, the plugin will not work.

So, this is the way it works:

  • With legacy redirect_uri parameter enabled in Keycloak, the plugin works in default mode.
  • With legacy redirect_uri parameter enabled in Keycloak, the plugin also works with legacy mode.
  • With legacy redirect_uri parameter disabled in Keycloak (default after version 18), the plugin works in default mode.
  • With legacy redirect_uri parameter disabled in Keycloak (default after version 18), the plugin does NOT work with legacy mode.

So, for Keycloak, it does not matter if we use the default or legacy mode if the Keycloak runs in legacy mode.

Notes:

Additional Documentation

Please refer to the Keycloak documentation for up to date instructions. Specifically, here we will use a Docker image, so follow the instructions on how to get started with Keycloak on Docker.

Setup Plone as a client

  • Make sure pas.plugins.oidc is installed.
  • Start Plone and create a Plone site with id Plone.
  • In the Add-ons control panel, install pas.plugins.oidc.
  • In the ZMI go to the plugin properties at http://localhost:8081/Plone/acl_users/oidc/manage_propertiesForm
  • Set these properties:
    • OIDC/Oauth2 Issuer: http://127.0.0.1:8081/realms/plone/
    • Client ID: plone (Warning: This property must match the Client ID you have set in Keycloak.)
    • Client secret: 12345678 (Warning: This property must match the Client secret you have get in Keycloak.)
    • Use deprecated redirect_uri for logout url checked. Use this if you need to run old versions of Keycloak.
    • Open ID scopes to request to the server: this depends on which version of Keycloak you are using, and which scopes are available there. In recent Keycloak versions, you must include openid as scope. Suggestion is to use openid and profile.
    • Tip: Leave the rest at the defaults, unless you know what you are doing.
    • Click Save.

Plone is ready done configured!

See this screenshot:

Login

Go to the other browser, or logout as admin from Keycloak Admin Console. Currently, the Plone login form is unchanged.

Instead, for testing go to the login page of the plugin: http://localhost:8081/Plone/acl_users/oidc/login, this will take you to Keycloak to login, and then return. You should now be logged in to Plone, and see the full name and email, if you have set this in Keycloak.

Logout

If the login did work as expected you can try to Plone logout. Currently, the Plone logout form is unchanged.

Instead, for testing go to the logout page of the plugin: http://localhost:8081/Plone/acl_users/oidc/logout, this will take you to Keycloak to logout, and then return to the post-logout redirect URL.

Technical Decisions

Usage of sessions in the login process

This plugin uses sessions during the login process to identify the user while he goes to the OIDC provider and comes back from there.

The plugin has 2 ways of working with sessions:

  • Use the Zope Session Management: if the Use Zope session data manager option in the plugin configuration is enabled, the plugin will use the sessioning configuration configured in Zope. To do so we advise using Products.mcdutils to save the session data in a memcached based storage. Otherwise Zope will try to use ZODB based sessioning which has shown several problems in the past.

  • Use the cookie-based session management: if the Use Zope session data manager option in the plugin configuration is disabled, the plugin will use a Cookie to save that information in the client's browser.

Settings in environment variables

Optionally, instead of editing your OIDC provider settings through the ZMI, you can use collective.regenv and provide a YAML file with your settings. This is very useful if you have different settings in different environments and you do not want to edit the settings each time you move the contents.

Varnish

Optionally, if you are using the Varnish caching server in front of Plone, you may see this plugin only partially working. Especially the came_from parameter may be ignored. This is because the buildout standard configuration from plone.recipe.varnish removes most cookies to improve anonymous caching.

The solution is to make sure the __ac_session cookie is added to the cookie-pass option. Check what the current default is in the buildout recipe, and update it:

Contribute

Local Development Setup

You need a working python environment (system, virtualenv, pyenv, etc) version 3.8 or superior.

Then install the dependencies and a development instance using:

make install

Start Local Server

Start Plone, on port 8080, with the command:

make start

Keycloak

The pas.plugins.oidc repository has a working setup for a Keycloak development server using Docker and Docker Compose. To use it, in a terminal, run the command:

make keycloak-start

There are two realms configured plone and plone-test. The later is used in automated tests, while the former should be used for your development environment.

The plone realm ships with an user that has the following credentials:

  • username: user
  • password: 12345678

To stop a running Keycloak (needed when running tests), use:

make keycloak-stop

Update translations

make i18n

Format codebase

make format

Run tests

Testing of this package is done with pytest and tox.

Run all tests with:

make test

Run all tests but stop on the first error and open a pdb session:

./bin/tox -e test -- -x --pdb

Run tests named TestServiceOIDCPost:

./bin/tox -e test -- -k TestServiceOIDCPost

References

License

The project is licensed under the GPLv2.

Contributors

Changelog

2.0.0b1 (2024-06-25)

New features:

  • Added Deutsch translation [@macagua] #45
  • Allow multiple instances of OIDC plugin in a given Plone site @erral #48
  • Notify user events on creation and authentication. [@Arkusm][@ericof] #53
  • Updated the latest .po templates for translate Updated Spanish translation [@macagua] #55

Internal:

  • Update configuration files @plone

Documentation:

  • Recommend using [pas.plugins.keycloakgroups](https://pypi-hypernode.com/project/pas.plugins.keycloakgroups/) for groups support with Keycloak [@ericof] #42

2.0.0a1 (2023-11-23)

New features:

  • Implement plone/meta and convert documentation to Markdown [@ericof] #32
  • Drop support to Python 2.7 and Plone 5.2 [@ericof] #33
  • Implement restapi services to handle authentication flow [@ericof] #38

Internal:

  • Rewrite tests from unittest to pytest with pytest-plone [@ericof] #34
  • Allow dict instances to hold userinfo [@erral] #35
  • Declare the minimum requirements for Plone/python in the readme [mamico] #36

1.0.0 (2023-11-11)

  • Allow dict instances to hold userinfo [@erral]

1.0a6 (2023-07-20)

  • Added Spanish translation [@macagua]

  • Added improvements about i18n support [macagua]

  • Drop python 2.7 and Plone 4 support [@erral]

  • Add support for the post_logout parameter for logout api. [@ramiroluz]

1.0a5 (2023-04-05)

  • Catch exceptions during the OAuth process [@erral]

  • Update the plugin to make challenges. An anonymous user who visits a page for which you have to be authenticated, is redirected to the new require_login view on the plugin. This works the same way as the standard require_login page of Plone. [@maurits]

  • Add a property for the default userinfo instead of using only sub. [@eikichi18]

1.0a4 (2023-01-16)

  • Call getProperty only once when getting redirect_uris or scope. [@maurits]

  • use getProperty accessor [@mamico]

1.0a3 (2022-10-30)

  • Removed the hardcoded auth cookie name [@alecghica]

  • Fixed Python compatibility with version >= 3.6 [@alecghica]

  • check if url is in portal before redirect #2 [@erral]

  • manage came_from [@mamico]

1.0a2 (unreleased)

  • do userinforequest if there is a client.userinfo_endpoint [@mamico]

1.0a1 (unreleased)

  • Initial release. [@mamico]

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pas.plugins.oidc-2.0.0b1.tar.gz (291.0 kB view hashes)

Uploaded Source

Built Distribution

pas.plugins.oidc-2.0.0b1-py3-none-any.whl (45.3 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page