From 9a2ecae02152302ab2cdb267c49ada619a144297 Mon Sep 17 00:00:00 2001 From: Martin Gross Date: Wed, 23 Feb 2022 10:32:16 +0100 Subject: [PATCH] Add pretix-presale-saml docs (#2468) --- doc/plugins/index.rst | 1 + doc/plugins/presale-saml.rst | 405 +++++++++++++++++++++++++++++++++++ 2 files changed, 406 insertions(+) create mode 100644 doc/plugins/presale-saml.rst diff --git a/doc/plugins/index.rst b/doc/plugins/index.rst index 70696d32fc..1b441794d8 100644 --- a/doc/plugins/index.rst +++ b/doc/plugins/index.rst @@ -19,3 +19,4 @@ If you want to **create** a plugin, please go to the digital imported_secrets webinar + presale-saml diff --git a/doc/plugins/presale-saml.rst b/doc/plugins/presale-saml.rst new file mode 100644 index 0000000000..129a2e428f --- /dev/null +++ b/doc/plugins/presale-saml.rst @@ -0,0 +1,405 @@ +.. highlight:: ini +.. spelling:: + + IdP + skIDentity + ePA + NPA + +Presale SAML Authentication +=========================== + +The Presale SAML Authentication plugin is an advanced plugin, which most event +organizers will not need to use. However, for the select few who do require +strong customer authentication that cannot be covered by the built-in customer +account functionality, this plugin allows pretix to connect to a SAML IdP and +perform authentication and retrieval of user information. + +Usage of the plugin is governed by two separate sets of settings: The plugin +installation, the Service Provider (SP) configuration and the event +configuration. + +Plugin installation and initial configuration +--------------------------------------------- + +.. note:: If you are a customer of our hosted `pretix.eu`_ offering, you can + skip this section. + +The plugin is installed as any other plugin in the pretix ecosystem. As a +pretix system administrator, please follow the instructions in the the +:ref:`Administrator documentation `. + +Once installed, you will need to assess, if you want (or need) your pretix +instance to be a single SP for all organizers and events or if every event +organizer has to provide their own SP. + +Take the example of a university which runs pretix under an pretix Enterprise +agreement. Since they only provide ticketing services to themselves (every +organizer is still just a different department of the same university), a +single SP should be enough. + +On the other hand, a reseller such as `pretix.eu`_ who services a multitude +of clients would not work that way. Here, every organizer is a separate +legal entity and as such will also need to provide their own SP configuration: +Company A will expect their SP to reflect their company - and not a generalized +"pretix SP". + +Once you have decided on the mode of operation, the :ref:`Configuration file +` needs to be extended to reflect your choice. + +Example:: + + [presale-saml] + level=global + +``level`` + ``global`` to use only a single, system-wide SP, ``organizer`` for multiple + SPs, configured on the organizer-level. Defaults to ``organizer``. + +Service Provider configuration +------------------------------ + +Global Level +^^^^^^^^^^^^ + +.. note:: If you are a customer of our hosted `pretix.eu`_ offering, you can + skip this section and follow the instructions on the upcoming + Organizer Level settings. + +As a user with administrative privileges, please activate them by clicking the +`Admin Mode` button in the top right hand corner. + +You should now see a new menu-item titled `SAML` appear. + +Organizer Level +^^^^^^^^^^^^^^^ + +Navigate to the organizer settings in the pretix backend. In the navigation +bar, you will find a menu-item titled `SAML` if your user has the `Can +change organizer settings` permission. + + +.. note:: If you are a customer of our hosted `pretix.eu`_ offering, the menu + will only appear once one of our friendly customer service agents + has enabled the Presale SAML Authentication plugin for at least one + of your events. Feel free to get in touch with us! + +Setting up the SP +^^^^^^^^^^^^^^^^^ + +No matter where your SP configuration lives, you will be greeted by a very +long list of fields of which almost all of them will need to be filled. Please +don't be discouraged - most of the settings don't need to be decided by yourself +and/or are already preset with a sensible default setting. + +If you are not sure what setting you should choose for any of the fields, you +should reach out to your IdP operator as they can tell you exactly what the IdP +expects and - more importantly - supports. + +``IdP Metadata URL`` + Please provide the URL where your IdP outputs its metadata. For most IdPs, + this URL is static and the same for all SPs. If you are a member of the + DFN-AAI, you can find the meta-data for the `Test-, Basic- and + Advanced-Federation`_ on their website. Please do talk with your local + IdP operator though, as you might not even need to go through the DFN-AAI + and might just use your institutions local IdP which will also host their + metadata on a different URL. + + The URL needs to be publicly accessible, as saving the settings form will + fail if the IdP metadata cannot be retrieved. pretix will also automatically + refresh the IdP metadata on a regular basis. + +``SP Entity Id`` + By default, we recommend that you use the system-proposed metadata-URL as + the Entity Id of your SP. However, if so desired or required by your IdP, + you can also set any other, arbitrary URL as the SP Entity Id. + +``SP Name / SP Decription`` + Most IdP will display the name and description of your SP to the users + during authentication. The description field can be used to explain to the + users how their data is being used. + +``SP X.509 Certificate / SP X.509 Private Key`` + Your SP needs a certificate and a private key for said certificate. Please + coordinate with your IdP, if you are supposed to generate these yourself or + if they are provided to you. + +``SP X.509 New Certificate`` + As certificates have an expiry date, they need to be renewed on a regular + basis. In order to facilitate the rollover from the expiring to the new + certificate, you can provide the new certificate already before the expiration + of the existing one. That way, the system will automatically use the correct + one. Once the old certificate has expired and is not used anymore at all, + you can move the new certificate into the slot of the normal certificate and + keep the new slot empty for your next renewal process. + +``Requested Attributes`` + An IdP can hold a variety of attributes of an authenticating user. While + your IdP will dictate which of the available attributes your SP can consume + in theory, you will still need to define exactly which attributes the SP + should request. + + The notation is a JSON list of objects with 5 attributes each: + + * ``attributeValue``: Can be defaulted to ``[]``. + * ``friendlyName``: String used in the upcoming event-level settings to + retrieve the attributes data. + * ``isRequired``: Boolean indicating whether the IdP must enforce the + transmission of this attribute. In most cases, ``true`` is the best + choice. + * ``name``: String of the internal, technical name of the requested + attribute. Often starting with ``urn:mace:dir:attribute-def:``, + ``urn:oid:`` or ``http://``/``https://``. + * ``nameFormat``: String describing the type of ``name`` that has been + set in the previous section. Often starting with + ``urn:mace:shibboleth:1.0:`` or ``urn:oasis:names:tc:SAML:2.0:``. + + Your IdP can provide you with a list of available attributes. See below + for a sample configuration in an academic context. + + Note, that you can have multiple attributes with the same ``friendlyName`` + but different ``name``s. This is often used in systems, where the same + information (for example a persons name) is saved in different fields - + for example because one institution is returning SAML 1.0 and other + institutions are returning SAML 2.0 style attributes. Typically, this only + occurs in mix environments like the DFN-AAI with a large number of + participants. If you are only using your own institutions IdP and not + authenticating anyone outside of your realm, this should not be a common + sight. + +``Encrypt/Sign/Require ...`` + Does what is says on the box - please inquire with your IdP for the + necessary settings. Most settings can be turned on as they increase security, + however some IdPs might stumble over some of them. + +``Signature / Digest Algorithm`` + Please chose appropriate algorithms, that both pretix/your SP and the IdP + can communicate with. A common source of issues when connecting to a + Shibboleth-based IdP is the Digest Algorithm: pretix does not support + ``http://www.w3.org/2009/xmlenc11#rsa-oaep`` and authentication will fail + if the IdP enforces this. + +``Technical/Support Contacts`` + Those contacts are encoded into the SPs public meta data and might be + displayed to users having trouble authenticating. It is recommended to + provide a dedicated point of contact for technical issues, as those will + be the ones to change the configuration for the SP. + +Event / Authentication configuration +------------------------------------ + +Basic settings +^^^^^^^^^^^^^^ + +Once the plugin has been enabled for a pretix event using the Plugins-menu from +the event's settings, a new *SAML* menu item will show up. + +On this page, the actual authentication can be configured. + +``Checkout Explanation`` + Since most users probably won't be familiar with why they have to authenticate + to buy a ticket, you can provide them a small blurb here. Markdown is supported. + +``Attribute RegEx`` + By default, any successful authentication with the IdP will allow the user to + proceed with their purchase. Should the allowed audience needed to be restricted + further, a set of regular Expressions can be used to do this. + + An Attribute RegEx of ``{}`` will allow any authenticated user to pass. + + A RegEx of ``{ "affiliation": "(employee@pretix.eu|staff@pretix.eu)" }`` will + only allow user to pass which have the ``affiliation`` attribute and whose + attribute either matches ``employee@pretix.eu`` or ``staff@pretix.eu``. + + Please make sure that the attribute you are querying is also requested from the + IdP in the first place - for a quick check you can have a look at the top of + the page where all currently configured attributes are listed. + +``RegEx Fail Explanation`` + Only used in conjunction with the above Attribute RegEx. Should the user not + pass the restrictions imposed by the regular expression, the user is shown + this error-message. + + If you are - for example in an university context - restricting access to + students only, you might want to explain here that Employees are not allowed + to book tickets. + +``Ticket Secret SAML Attribute`` + In very specific instances, it might be desirable that the ticket-secret is + not the randomly one generated by pretix but rather based on one of the + users attributes - for example their unique ID or access card number. + + To achieve this, the name of a SAML-attribute can be specified here. + + It is however necessary to note, that even with this setting in use, + ticket-secrets need to be unique. This is why when this setting is enabled, + the default, pretix-generated ticket-secret is prefixed with the attributes + value. + + Example: A users ``cardid`` attribute has the value of ``01189998819991197253``. + The default random ticket secret would have been + ``yczygpw9877akz2xwdhtdyvdqwkv7npj``. The resulting new secret will now be + ``01189998819991197253_yczygpw9877akz2xwdhtdyvdqwkv7npj``. + + That way, the ticket secret is still unique, but when checking into an event, + the user can easily be searched and found using their identifier. + +IdP-provided E-Mail addresses, names +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +By default, pretix will only authenticate the user and not process the received +data any further. + +However, there are a few exceptions to this rule. + +There are a few `magic` attributes that pretix will use to automatically populate +the corresponding fields within the checkout process **and lock them out from +user editing**. + + * ``givenName`` and ``sn``: If both of those attributes are present and pretix + is configured to collect the users name, these attributes' values are used + for the given and family name respectively. + * ``email``: If this attribute is present, the E-Mail-address of the users will + be set to the one transmitted through the attributes. + +The latter might pose a problem, if the IdP is transmitting an ``email`` attribute +which does contain a system-level mail address which is only used as an internal +identifier but not as a real mailbox. In this case, please consider setting the +``friendlyName`` of the attribute to a different value than ``email`` or removing +this field from the list of requested attributes altogether. + +Saving attributes to questions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +By setting the ``internal identifier`` of a user-defined question to the same name +as a SAML attribute, pretix will save the value of said attribute into the question. + +All the same as in the above section on E-Mail addresses, those fields become +non-editable by the user. + +Please be aware that some specialty question types might not be compatible with +the SAML attributes due to specific format requirements. If in doubt (or if the +checkout fails/the information is not properly saved), try setting the question +type to a simple type like "Text (one line)". + +Notes and configuration examples +-------------------------------- + +Requesting SAML 1.0 and 2.0 attributes from an academic IdP +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This requests the ``eduPersonPrincipalName`` (also sometimes called EPPN), +``email``, ``givenName`` and ``sn`` both in SAML 1.0 and SAML 2.0 attributes. + +.. sourcecode:: json + + [ + { + "attributeValue": [], + "friendlyName": "eduPersonPrincipalName", + "isRequired": true, + "name": "urn:mace:dir:attribute-def:eduPersonPrincipalName", + "nameFormat": "urn:mace:shibboleth:1.0:attributeNamespace:uri" + }, + { + "attributeValue": [], + "friendlyName": "eduPersonPrincipalName", + "isRequired": true, + "name": "urn:oid:1.3.6.1.4.1.5923.1.1.1.6", + "nameFormat": "urn:oasis:names:tc:SAML:2.0:attrname-format:uri" + }, + { + "attributeValue": [], + "friendlyName": "email", + "isRequired": true, + "name": "urn:mace:dir:attribute-def:mail", + "nameFormat": "urn:mace:shibboleth:1.0:attributeNamespace:uri" + }, + { + "attributeValue": [], + "friendlyName": "email", + "isRequired": true, + "name": "urn:oid:0.9.2342.19200300.100.1.3", + "nameFormat": "urn:oasis:names:tc:SAML:2.0:attrname-format:uri" + }, + { + "attributeValue": [], + "friendlyName": "givenName", + "isRequired": true, + "name": "urn:mace:dir:attribute-def:givenName", + "nameFormat": "urn:mace:shibboleth:1.0:attributeNamespace:uri" + }, + { + "attributeValue": [], + "friendlyName": "givenName", + "isRequired": true, + "name": "urn:oid:2.5.4.42", + "nameFormat": "urn:oasis:names:tc:SAML:2.0:attrname-format:uri" + }, + { + "attributeValue": [], + "friendlyName": "sn", + "isRequired": true, + "name": "urn:mace:dir:attribute-def:sn", + "nameFormat": "urn:mace:shibboleth:1.0:attributeNamespace:uri" + }, + { + "attributeValue": [], + "friendlyName": "sn", + "isRequired": true, + "name": "urn:oid:2.5.4.4", + "nameFormat": "urn:oasis:names:tc:SAML:2.0:attrname-format:uri" + } + ] + +skIDentity IdP Metadata URL +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Since the IdP Metadata URL for `skIDentity`_ is not readily documented/visible +in their backend, we document it here: +``https://service.skidentity.de/fs/saml/metadata`` + +Requesting skIDentity attributes for electronic identity cards +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This requests the basic ``eIdentifier``, ``IDType``, ``IDIssuer``, and +``NameID`` from the `skIDentity`_ SAML service, which are available for +electronic ID cards such as the German ePA/NPA. (Other attributes such as +the name and address are available at additional cost from the IdP). + +.. sourcecode:: json + + [ + { + "attributeValue": [], + "friendlyName": "eIdentifier", + "isRequired": true, + "name": "http://www.skidentity.de/att/eIdentifier", + "nameFormat": "urn:oasis:names:tc:SAML:2.0:attrname-format:uri" + }, + { + "attributeValue": [], + "friendlyName": "IDType", + "isRequired": true, + "name": "http://www.skidentity.de/att/IDType", + "nameFormat": "urn:oasis:names:tc:SAML:2.0:attrname-format:uri" + }, + { + "attributeValue": [], + "friendlyName": "IDIssuer", + "isRequired": true, + "name": "http://www.skidentity.de/att/IDIssuer", + "nameFormat": "urn:oasis:names:tc:SAML:2.0:attrname-format:uri" + }, + { + "attributeValue": [], + "friendlyName": "NameID", + "isRequired": true, + "name": "http://www.skidentity.de/att/NameID", + "nameFormat": "urn:oasis:names:tc:SAML:2.0:attrname-format:uri" + } + ] + +.. _pretix.eu: https://pretix.eu +.. _Test-, Basic- and Advanced-Federation: https://doku.tid.dfn.de/en:metadata +.. _skIDentity: https://www.skidentity.de/ \ No newline at end of file