wcs.samlauth


Namewcs.samlauth JSON
Version 1.0.0a4 PyPI version JSON
download
home_pagehttps://pypi.python.org/pypi/wcs.samlauth
SummarySAML authentication for plone sites
upload_time2024-02-21 00:37:00
maintainer
docs_urlNone
authorMathias Leimgruber
requires_python
licenseGPL version 2
keywords plone authentication saml
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # wcs.samlauth

wcs.samlauth is a saml authentication plugin based on python3-saml for plone 6.
It turns your plone site into a SP (Service Provider).
IDP (Identity Provider) is not supported.

The package is tested with plone 6 and python 3.11. It does not officially support other versions.

## Goal

Make it as easy as possible to configure plone as a SP (Service Provider), without having a in depth knowledge of SAML and how it works under the hood. This package uses the high level API of python3-saml, which makes it easy to configure and use.


## TL;DR

1. Install wcs.samlauth plugin
2. Add PAS plugin via ZMI (in acl_users)
3. Go to http://localhost:8080/Plone/acl_users/saml/idp_metadata
4. Fetch or upload IDP metadata -> Click "Get and store metadata"
5. Go to http://localhost:8080/Plone/acl_users/saml/metadata and configure your IDP
6. Use http://localhost:8080/Plone/acl_users/saml/sls to login via IDP


## Architecure

The plugin is based on a similar architecture/concept as [pas.plugins.oidc](https://github.com/collective/pas.plugins.oidc/). It basically means that all endpoints are directly on the plugin.
The plugin does not override plones login/logout views. This is up to you.
If you only have one saml plugin it's possible to enable the **Challenge** plugin, which redirects to the saml login endpoint.

This enables you to add multiple saml plugins as well.

### Dependecies:

See [python3-saml](https://github.com/SAML-Toolkits/python3-saml)
Make especially sure the following packages can be installed, since the have some system dependencies as well:

- [xmlsec](https://pypi.org/project/xmlsec/)
- [lxml](https://pypi.org/project/lxml/)

For example, on a recent Ubuntu, you should run:
```shell
apt install pkg-config libxml2-dev libxmlsec1-dev libxmlsec1-openssl
```

## Endpoints


Given the ID of the SAML plugin is "saml":

- Expose SP metadata on http://localhost:8080/Plone/acl_users/saml/metadata
    - the SP metadata is partially generated and partially static. entityId, assertionConsumerService and singleLogoutService are generated
- SAML Login endpoint is http://localhost:8080/Plone/acl_users/saml/sls
- SAML ACS endpoint is http://localhost:8080/Plone/acl_users/saml/acs
- SAML Logout endpoint is http://localhost:8080/Plone/acl_users/saml/slo
- SAML SP initiated logout endpoint http://localhost:8080/Plone/acl_users/saml/logout
- Fetch IDP metadata http://localhost:8080/Plone/acl_users/saml/idp_metadata


## Features

- Fetch and store IDP metadata via IDP metadata endpoint
- Upload and store IDP metadata via file upload
- Multiple saml plugins at the same time
- Implements almost everything from python3-saml, this includes SP signing of the AuthnRequest and metadata
- Create a plone session and/or restapi token
- Enable/Disable the creation of a plone user
- Automatically updates user data (hardcoded, currently limited to email and fullname)
- Enable/Disable the validation of authn requests (Uses temporarly a `__saml` cookie)
- Prevent Redirect attacks, by validating the RelayState parameter and a and an "allowed" list of domains, where we can redirect to
- E2E tests with Keykloak as IDP in different configuration variations
- Manually tested with Azure AD as IDP
- Documentation use azure and keycloak as IDP


## Installation


Add plugin to your buildout
```
[buildout]

...

eggs =
    wcs.samlauth
```


Add wcs.samlauth to plone docker image
```
$ docker run -p 8080:8080 -e SITE="mysite" -e ADDONS="wcs.samlauth" plone
```

From the ZMI go to `acl_users` and add the saml plugin.


## Development

It's best to use a local IDP, for example keycloak in order to make changes to this package.

Start a local keycloak server using docker:

```
$ docker run -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak:22.0.2 start-dev

```

Install and run a test plone instance:

```
$ git clone git@github.com:webcloud7/wcs.samlauth.git && cd wcs.samlauth
$ make install
$ make run
```


# Test

You need a local docker installation to run tests.

The package provides a docker test layer, which spins up keycloak and loads various configuration files into keycloak.


```
$ make test
```

Run individual tests:

```
$ ./bin/test -t test_whatever
```

# HowTo's

The tests/assets folder contains some keycloak configurations you can use for your test setup.
It inclues examples with SP signed autn requests and metadata.

The examples below do not use this specific saml feature which is required by most IDP.

## Manuall configuiration

You can configure everythin manully as well. Please see the [python3-saml documentation](https://github.com/SAML-Toolkits/python3-saml/blob/v1.15.0/README.md) for details

The configuration needs to be applied directly on the property tab of the saml plugin.


## Configure with keycloak as IDP

For both create a new saml pas plugin via ZMI in acl_users

### IDP part on keycloak

1. Login to your Keycloak admin console.

2. Create a new realm or use one that's already there. If not there create a test user.

3. With the data from http://localhost:8080/Plone/acl_users/saml/metadata create a new Client.

    Client type is SAML.

    Important note here: The client ID is identical to the SAML `EntityID`
    For example http://localhost:8080/keycloak/acl_users/saml/metadata

    ![Create keycloak client](./docs/images/keycloak_create_client.png?raw=true "Create keycloak client")

    Click "next"

4. Configure Home URL and Valid redirect URLs

    ![Configure keycloak](./docs/images/keycloak_config.png?raw=true "Configure keycloak")

    Click "Save"

5. Go to "Keys" tab and disable "Client signature required" 

    ![Disable signing](./docs/images/keycloak_disable.png?raw=true "Disable signing")

6. Configure attribute bindings

    Unter "Client scopes" click on URL which ends with /metadata-dedicated

    ![Disable signing](./docs/images/keycloak_scope.png?raw=true "Disable signing")

    Click on "Add predefined mapper"

    Chose the following mappers
    ![Disable signing](./docs/images/keycloak_attrs.png?raw=true "Disable signing")

    Click "Add"

7. Go to the Advance tab and configure the logout service redirect binding (python3-saml only supports the redirect binding here)

    ![Configure keycloak advanced](./docs/images/keycloak_advanced.png?raw=true "Configure keycloak advanced")

8. Copy the metadataa saml config URL

    ![copy url](./docs/images/keycloak_url.png?raw=true "copy url")

### SP part on your Plone site

1. Go to URL: http://localhost:8080/Plone/acl_users/saml/idp_metadata

    Enter the Url and Click on "Get and store metadata"

    ![copy url](./docs/images/plone_url.png?raw=true "copy url")    

    Hints: Keycloak has `authnRequestsSigned: true` hardcoded. 

**THATS IT!! Go To http://localhost:8080/Plone/acl_users/saml/sls to login via azure**

If this is the only saml plugin on your site and want all users to login via saml, then you can enable the Challenge Plugin and change the login and logout actions on your plone site to use the saml endpoints.


## Configure with Azure as IDP

This is a tutorial how to configure an azure cloud enterprise app as IDP for this plugin.

### IDP part on azure cloud

1. Go to your azure AD and create a new enterprise app.
    
    ![Create azure enterprise app](./docs/images/azure_create_app.png?raw=true "Create azure enterprise app")

2. Go to the "Single Sign on" section.

    ![SSO section](./docs/images/azure_sso.png?raw=true "SSO section")

3. Add SAML authentification to app.

    ![Add SAML](./docs/images/azure_saml.png?raw=true "Add SAML")

4. Gather the metadata from the SAML plugin.

    URL: http://localhost:8080/Plone/acl_users/saml/metadata

    ![Get metadata](./docs/images/plone_get_metadata.png?raw=true "Get metadata")

4. Manually edit "Basic SAML Configuration" (Info's can be taken from the SP metadata xml)

    Add EntityID and ACS. Optionally also add the Logout URL. Azure wants https there, so depending on your setup
    just leave it blank.

    ![Edit basic saml](./docs/images/azure_edit_basic.png?raw=true "Edit basic saml")

5. Edit "Attributes & Claims"
    
    The plugin only supports the email address, given name and surename
    You can configure more attributes, but they will be ignored.

    Important: The clame names need to be givenName, surename and email.
    Also remove the namespace and leave empty.
    
    ![Edit attrs](./docs/images/azure_attrs.png?raw=true "Edit attrs")

6. Download Federation metadata XML

    ![Download metadata](./docs/images/azure_download.png?raw=true "Download metadata")

### SP part on your Plone site

1. Go to URL: http://localhost:8080/Plone/acl_users/saml/idp_metadata

    Upload and store configuration from IDP (azure)

    ![Upload xml](./docs/images/plone_upload.png?raw=true "Upload xml")

2. The upload form also shows you what information has been gathered from the Metadata XML and what will be stored in your saml plugin

    ![Info xml](./docs/images/plone_info.png?raw=true "Info xml")

**THATS IT!! Go To http://localhost:8080/Plone/acl_users/saml/sls to login via azure**

If this is the only saml plugin on your site and want all users to login via saml, then you can enable the Challenge Plugin and change the login and logout actions on your plone site to use the saml endpoints.


Changelog
=========


1.0.0a4 (2024-02-20)
--------------------

- Do not use SCRIPT_NAME for the callback URL. [mathias.leimgruber]


1.0.0a3 (2023-09-28)
--------------------

- Fix typo for boolean property. [mathias.leimgruber]


1.0.0a2 (2023-09-28)
--------------------

- Disable csrf protection on acs (callback view). [mathias.leimgruber]


1.0.0a1 (2023-09-28)
--------------------

- Init release [mathias.leimgruber]

            

Raw data

            {
    "_id": null,
    "home_page": "https://pypi.python.org/pypi/wcs.samlauth",
    "name": "wcs.samlauth",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "Plone Authentication SAML",
    "author": "Mathias Leimgruber",
    "author_email": "m.leimgruber@webcloud7.ch",
    "download_url": "https://files.pythonhosted.org/packages/a3/d4/9ed94446cd77e246ad00358fbed52f9eab910a30351c99942a189190dcb0/wcs.samlauth-1.0.0a4.tar.gz",
    "platform": null,
    "description": "# wcs.samlauth\n\nwcs.samlauth is a saml authentication plugin based on python3-saml for plone 6.\nIt turns your plone site into a SP (Service Provider).\nIDP (Identity Provider) is not supported.\n\nThe package is tested with plone 6 and python 3.11. It does not officially support other versions.\n\n## Goal\n\nMake it as easy as possible to configure plone as a SP (Service Provider), without having a in depth knowledge of SAML and how it works under the hood. This package uses the high level API of python3-saml, which makes it easy to configure and use.\n\n\n## TL;DR\n\n1. Install wcs.samlauth plugin\n2. Add PAS plugin via ZMI (in acl_users)\n3. Go to http://localhost:8080/Plone/acl_users/saml/idp_metadata\n4. Fetch or upload IDP metadata -> Click \"Get and store metadata\"\n5. Go to http://localhost:8080/Plone/acl_users/saml/metadata and configure your IDP\n6. Use http://localhost:8080/Plone/acl_users/saml/sls to login via IDP\n\n\n## Architecure\n\nThe plugin is based on a similar architecture/concept as [pas.plugins.oidc](https://github.com/collective/pas.plugins.oidc/). It basically means that all endpoints are directly on the plugin.\nThe plugin does not override plones login/logout views. This is up to you.\nIf you only have one saml plugin it's possible to enable the **Challenge** plugin, which redirects to the saml login endpoint.\n\nThis enables you to add multiple saml plugins as well.\n\n### Dependecies:\n\nSee [python3-saml](https://github.com/SAML-Toolkits/python3-saml)\nMake especially sure the following packages can be installed, since the have some system dependencies as well:\n\n- [xmlsec](https://pypi.org/project/xmlsec/)\n- [lxml](https://pypi.org/project/lxml/)\n\nFor example, on a recent Ubuntu, you should run:\n```shell\napt install pkg-config libxml2-dev libxmlsec1-dev libxmlsec1-openssl\n```\n\n## Endpoints\n\n\nGiven the ID of the SAML plugin is \"saml\":\n\n- Expose SP metadata on http://localhost:8080/Plone/acl_users/saml/metadata\n    - the SP metadata is partially generated and partially static. entityId, assertionConsumerService and singleLogoutService are generated\n- SAML Login endpoint is http://localhost:8080/Plone/acl_users/saml/sls\n- SAML ACS endpoint is http://localhost:8080/Plone/acl_users/saml/acs\n- SAML Logout endpoint is http://localhost:8080/Plone/acl_users/saml/slo\n- SAML SP initiated logout endpoint http://localhost:8080/Plone/acl_users/saml/logout\n- Fetch IDP metadata http://localhost:8080/Plone/acl_users/saml/idp_metadata\n\n\n## Features\n\n- Fetch and store IDP metadata via IDP metadata endpoint\n- Upload and store IDP metadata via file upload\n- Multiple saml plugins at the same time\n- Implements almost everything from python3-saml, this includes SP signing of the AuthnRequest and metadata\n- Create a plone session and/or restapi token\n- Enable/Disable the creation of a plone user\n- Automatically updates user data (hardcoded, currently limited to email and fullname)\n- Enable/Disable the validation of authn requests (Uses temporarly a `__saml` cookie)\n- Prevent Redirect attacks, by validating the RelayState parameter and a and an \"allowed\" list of domains, where we can redirect to\n- E2E tests with Keykloak as IDP in different configuration variations\n- Manually tested with Azure AD as IDP\n- Documentation use azure and keycloak as IDP\n\n\n## Installation\n\n\nAdd plugin to your buildout\n```\n[buildout]\n\n...\n\neggs =\n    wcs.samlauth\n```\n\n\nAdd wcs.samlauth to plone docker image\n```\n$ docker run -p 8080:8080 -e SITE=\"mysite\" -e ADDONS=\"wcs.samlauth\" plone\n```\n\nFrom the ZMI go to `acl_users` and add the saml plugin.\n\n\n## Development\n\nIt's best to use a local IDP, for example keycloak in order to make changes to this package.\n\nStart a local keycloak server using docker:\n\n```\n$ docker run -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak:22.0.2 start-dev\n\n```\n\nInstall and run a test plone instance:\n\n```\n$ git clone git@github.com:webcloud7/wcs.samlauth.git && cd wcs.samlauth\n$ make install\n$ make run\n```\n\n\n# Test\n\nYou need a local docker installation to run tests.\n\nThe package provides a docker test layer, which spins up keycloak and loads various configuration files into keycloak.\n\n\n```\n$ make test\n```\n\nRun individual tests:\n\n```\n$ ./bin/test -t test_whatever\n```\n\n# HowTo's\n\nThe tests/assets folder contains some keycloak configurations you can use for your test setup.\nIt inclues examples with SP signed autn requests and metadata.\n\nThe examples below do not use this specific saml feature which is required by most IDP.\n\n## Manuall configuiration\n\nYou can configure everythin manully as well. Please see the [python3-saml documentation](https://github.com/SAML-Toolkits/python3-saml/blob/v1.15.0/README.md) for details\n\nThe configuration needs to be applied directly on the property tab of the saml plugin.\n\n\n## Configure with keycloak as IDP\n\nFor both create a new saml pas plugin via ZMI in acl_users\n\n### IDP part on keycloak\n\n1. Login to your Keycloak admin console.\n\n2. Create a new realm or use one that's already there. If not there create a test user.\n\n3. With the data from http://localhost:8080/Plone/acl_users/saml/metadata create a new Client.\n\n    Client type is SAML.\n\n    Important note here: The client ID is identical to the SAML `EntityID`\n    For example http://localhost:8080/keycloak/acl_users/saml/metadata\n\n    ![Create keycloak client](./docs/images/keycloak_create_client.png?raw=true \"Create keycloak client\")\n\n    Click \"next\"\n\n4. Configure Home URL and Valid redirect URLs\n\n    ![Configure keycloak](./docs/images/keycloak_config.png?raw=true \"Configure keycloak\")\n\n    Click \"Save\"\n\n5. Go to \"Keys\" tab and disable \"Client signature required\" \n\n    ![Disable signing](./docs/images/keycloak_disable.png?raw=true \"Disable signing\")\n\n6. Configure attribute bindings\n\n    Unter \"Client scopes\" click on URL which ends with /metadata-dedicated\n\n    ![Disable signing](./docs/images/keycloak_scope.png?raw=true \"Disable signing\")\n\n    Click on \"Add predefined mapper\"\n\n    Chose the following mappers\n    ![Disable signing](./docs/images/keycloak_attrs.png?raw=true \"Disable signing\")\n\n    Click \"Add\"\n\n7. Go to the Advance tab and configure the logout service redirect binding (python3-saml only supports the redirect binding here)\n\n    ![Configure keycloak advanced](./docs/images/keycloak_advanced.png?raw=true \"Configure keycloak advanced\")\n\n8. Copy the metadataa saml config URL\n\n    ![copy url](./docs/images/keycloak_url.png?raw=true \"copy url\")\n\n### SP part on your Plone site\n\n1. Go to URL: http://localhost:8080/Plone/acl_users/saml/idp_metadata\n\n    Enter the Url and Click on \"Get and store metadata\"\n\n    ![copy url](./docs/images/plone_url.png?raw=true \"copy url\")    \n\n    Hints: Keycloak has `authnRequestsSigned: true` hardcoded. \n\n**THATS IT!! Go To http://localhost:8080/Plone/acl_users/saml/sls to login via azure**\n\nIf this is the only saml plugin on your site and want all users to login via saml, then you can enable the Challenge Plugin and change the login and logout actions on your plone site to use the saml endpoints.\n\n\n## Configure with Azure as IDP\n\nThis is a tutorial how to configure an azure cloud enterprise app as IDP for this plugin.\n\n### IDP part on azure cloud\n\n1. Go to your azure AD and create a new enterprise app.\n    \n    ![Create azure enterprise app](./docs/images/azure_create_app.png?raw=true \"Create azure enterprise app\")\n\n2. Go to the \"Single Sign on\" section.\n\n    ![SSO section](./docs/images/azure_sso.png?raw=true \"SSO section\")\n\n3. Add SAML authentification to app.\n\n    ![Add SAML](./docs/images/azure_saml.png?raw=true \"Add SAML\")\n\n4. Gather the metadata from the SAML plugin.\n\n    URL: http://localhost:8080/Plone/acl_users/saml/metadata\n\n    ![Get metadata](./docs/images/plone_get_metadata.png?raw=true \"Get metadata\")\n\n4. Manually edit \"Basic SAML Configuration\" (Info's can be taken from the SP metadata xml)\n\n    Add EntityID and ACS. Optionally also add the Logout URL. Azure wants https there, so depending on your setup\n    just leave it blank.\n\n    ![Edit basic saml](./docs/images/azure_edit_basic.png?raw=true \"Edit basic saml\")\n\n5. Edit \"Attributes & Claims\"\n    \n    The plugin only supports the email address, given name and surename\n    You can configure more attributes, but they will be ignored.\n\n    Important: The clame names need to be givenName, surename and email.\n    Also remove the namespace and leave empty.\n    \n    ![Edit attrs](./docs/images/azure_attrs.png?raw=true \"Edit attrs\")\n\n6. Download Federation metadata XML\n\n    ![Download metadata](./docs/images/azure_download.png?raw=true \"Download metadata\")\n\n### SP part on your Plone site\n\n1. Go to URL: http://localhost:8080/Plone/acl_users/saml/idp_metadata\n\n    Upload and store configuration from IDP (azure)\n\n    ![Upload xml](./docs/images/plone_upload.png?raw=true \"Upload xml\")\n\n2. The upload form also shows you what information has been gathered from the Metadata XML and what will be stored in your saml plugin\n\n    ![Info xml](./docs/images/plone_info.png?raw=true \"Info xml\")\n\n**THATS IT!! Go To http://localhost:8080/Plone/acl_users/saml/sls to login via azure**\n\nIf this is the only saml plugin on your site and want all users to login via saml, then you can enable the Challenge Plugin and change the login and logout actions on your plone site to use the saml endpoints.\n\n\nChangelog\n=========\n\n\n1.0.0a4 (2024-02-20)\n--------------------\n\n- Do not use SCRIPT_NAME for the callback URL. [mathias.leimgruber]\n\n\n1.0.0a3 (2023-09-28)\n--------------------\n\n- Fix typo for boolean property. [mathias.leimgruber]\n\n\n1.0.0a2 (2023-09-28)\n--------------------\n\n- Disable csrf protection on acs (callback view). [mathias.leimgruber]\n\n\n1.0.0a1 (2023-09-28)\n--------------------\n\n- Init release [mathias.leimgruber]\n",
    "bugtrack_url": null,
    "license": "GPL version 2",
    "summary": "SAML authentication for plone sites",
    "version": "1.0.0a4",
    "project_urls": {
        "Homepage": "https://pypi.python.org/pypi/wcs.samlauth"
    },
    "split_keywords": [
        "plone",
        "authentication",
        "saml"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "a3d49ed94446cd77e246ad00358fbed52f9eab910a30351c99942a189190dcb0",
                "md5": "05ec74dd32904569d3c03e1d3707dcbd",
                "sha256": "dc88ef75c2944d7d596eaa7149d0c96909185146857a9e08100a39b475900f65"
            },
            "downloads": -1,
            "filename": "wcs.samlauth-1.0.0a4.tar.gz",
            "has_sig": false,
            "md5_digest": "05ec74dd32904569d3c03e1d3707dcbd",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 1194008,
            "upload_time": "2024-02-21T00:37:00",
            "upload_time_iso_8601": "2024-02-21T00:37:00.930518Z",
            "url": "https://files.pythonhosted.org/packages/a3/d4/9ed94446cd77e246ad00358fbed52f9eab910a30351c99942a189190dcb0/wcs.samlauth-1.0.0a4.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-02-21 00:37:00",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "wcs.samlauth"
}
        
Elapsed time: 0.18437s