From 005b319f23b287a599b2c2727ef8af6339712598 Mon Sep 17 00:00:00 2001 From: totl Date: Tue, 12 Nov 2024 17:50:58 +0000 Subject: [PATCH 01/10] added more marked-up SAML Config instructions --- doc/SAML-Configuration.md | 132 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 doc/SAML-Configuration.md diff --git a/doc/SAML-Configuration.md b/doc/SAML-Configuration.md new file mode 100644 index 000000000..85fcc4e9e --- /dev/null +++ b/doc/SAML-Configuration.md @@ -0,0 +1,132 @@ +**It is important to make sure registration.require.email.activation is set to false in Application Configuration. If +email activation is enabled users will never be able to log in.** + +### LibreBooking SAML Introduction + +LibreBooking comes with multiple Single Sign On +plugins out of the box. There are many benefits to SSO over standard authentication. For administrators, having a single +point of account credential and access administration is very valuable. If someone leaves the organization they don’t +have to deactivate accounts in multiple systems. For your normal user, the benefit is not having to register and +remember yet another set of application credentials. + +In this post we’ll cover how to set up SSO with SAML. Most SSO +configurations for LibreBooking are pretty straightforward – you just update the configuration options for the plugin. +But SAML is different. SAML requires a 3rd party application +called [SimpleSAMLphp](http://web.archive.org/web/20210303172340/https://simplesamlphp.org/) to be running on the same +server as LibreBooking. + +### Install SimpleSAMLphp + +Our first step is to download the latest version +of [SimpleSAMLphp](http://web.archive.org/web/20210303172340/https://simplesamlphp.org/) and install it on your web +server. I recommend installing it outside your publicly visible directories and set up a subdomain pointing to the +www directory. For example, if you install it to `/home/username/simplesamlphp` and you have LibreBookingrunning out of +`/home/username/public\_html/librebooking`, then you’d create a subdomain such as `saml.librebooking.xpto` pointing to +`/home/username/simplesamlphp/www`. The reason we do this is because the only files which need to be publicly visible in +SimpleSAMLphp are located in the www directory. Exposing more than that opens unnecessary security holes. + +### Configure SimpleSAMLphp + +SimpleSAMLphp has a lot of configuration options. If you’re like me and far from an expert in SAML, it’s overwhelming. +Luckily, since LibreBooking is a Service Provider it doesn’t need anything special. I’ll go through each of the settings +that need to be updated individually. Please note that at the time of writing this post, the latest version of +SimpleSAMLphp was 1.18.5. It’s possible that the names of the options will change in future versions. + +Open up `/home/username/simplesamlphp/config/config.php` with a text editor. + +`baseurlpath` +: Set this to the full path of the SimpleSAMLphp WWW directory. If you followed the above advice and created a +subdomain, this should be something like `https://saml.yourdomain.com` + +`technicalcontact_email` +: Your email address (or anyone responsible for managing SSO integrations) + +`secretsalt` +: Set this to any secure, random value. + +`auth.adminpassword` +: Set this to any secure, random value, you will use this to access the admin page of the web UI for SimpleSAML. + +`trusted.url.domains` +: This should be set to an array of domains that will participate in the SSO +handshake. I use `array(‘saml.librebooking.com’, ‘librebooking.com’)` + +`session.cookie.domain` +: This should be set to the wildcard subdomain of your primary domain. For example, I use `.librebooking.com` + +`session.cookie.secure` +: This should be set to true, assuming all traffic is sent over https. + +`store.type` +: Set this to `sql`. This ensures that PHP sessions +from LibreBooking and sessions from SimpleSAMLphp do not conflict. + +`store.sql.dsn` +: should be set to a writable location for the sqlite database. You **must** have SQLite support in PHP enabled for this +to work. Alternatively, you can set up +any PDO supported database to store session data. Since I use SQLite, I have this set to something +like `sqlite:/home/username/tmp/sqlitedatabase.sq3` + +### Exchange Metadata + +Now that we have the configuration set, we’ll need to exchange metadata. + +The first thing to do is get the metadata XML +from the Identity Provider that you’re integrating with. For example in Azure apps you can find this under Manage -> +Single sign-on -> SAML Certificates -> Federation Metadata XML + +SimpleSAMLphp has a handy metadata XML conversion tool, which +we’ll use to finish up our configuration. + +* Open the admin page from the subdomain for SimpleSAMLphp in a + browser (https://saml.librebooking.com/admin was what I used). +* You’ll be prompted to enter the _auth.adminpassword_ that you set in your config.php +* Click on the _Federation_ tab +* then the _XML to SimpleSAMLphp metadata converter_ link. +* Paste in the XML or, if you have it saved to a file, upload it. +* SimpleSAMLphp will output at least one PHP version of that + metadata. +* For each one of those, location the file with the same name in `/home/username/simplesamlphp/metadata`. The + most common files it tells you to update will be `saml20-idp-remote.php` or `shib13-idp-remote.php` Delete everything except the + opening php tag, then paste in the output from SimpleSAMLphp. +* Copy the value of the `entityid` (usually found on the 3rd + line of that file) +* Open up `/simplesamlphp/config/authsources.php` +* Find the `idp` setting, and paste the value of the `entityid` there. + +### Update SAML Configuration in LibreBooking + +Whew, almost done. The last few settings are in LibreBooking. First, open up +_/your-librebooking-directory/config/config.php_, find the authentication setting in the plugins section and set the +value to _Saml_. `$conf['settings']['plugins']['Authentication'] = 'Saml';` Open up +_/your-librebooking-directory/plugins/Authentication/Saml_ and copy _Saml.config.dist.php_ to _Saml.config.php_. Open +_Saml.config.php_ in an editor. _simplesamlphp.lib_ should be updated to the root filesystem directory of SimpleSAMLphp. +If you’re using the settings I described here, this would be _/home/username/simplesamlphp_. _simplesamlphp.config_ +should be updated to the config filesystem directory for SimpleSAMLphp. In this case +_/home/username/simplesamlphp/config_ Most of the remaining settings are attribute maps. SAML will send over user +attributes, but often with obscure names. LibreBooking needs to know which attribute maps to the proper user field in +LibreBooking. There are only 2 absolutely required fields to map – username/userid and email. For example, if the +username is being sent across in the SAML payload as _urn:oid:0.1.2.3_ you’d set _simplesamlphp.username_ to this value +like _$conf\[‘settings’\]\[‘simplesamlphp.username’\] = ‘urn:oid:0.1.2.3’;_ This is the same for all the other +attributes. If you don’t know the attributes coming across then you can add the following line to +plugins/Authentication/Saml/SamlUser.php as the first line in the +constructor. `Log::Debug('Saml attributes are: %s', var_export($saml_attributes, true));` Enable Logging in LibreBooking +and try to log in. We’ll write out the attributes to the log file and you can copy the names into the LibreBooking SAML +configuration file. + +### Some Restrictions + +A couple important notes with SAML enabled: + +The first is that you will no longer be able to log into LibreBooking with +any other credentials. There is no “back door” – so every authentication request will be routed through SAML. + +The other restriction is that you will not be able to use any authenticated method from the API. SAML performs a series of browser +redirects in order to complete the authentication process. When using the API you are not within the context of a +browser, so authentication will fail. + +### Logging In + +Once all the mapping is complete, you should be able to log into LibreBooking via your organization’s federated log in +page. Your users will no longer have to remember another set of credentials and your account management just got one +step easier! From f82780dae33351b0db404ac8a91a2b30c21dfdc3 Mon Sep 17 00:00:00 2001 From: totl Date: Tue, 12 Nov 2024 17:55:59 +0000 Subject: [PATCH 02/10] update --- doc/SAML-Configuration.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/SAML-Configuration.md b/doc/SAML-Configuration.md index 85fcc4e9e..cec77af00 100644 --- a/doc/SAML-Configuration.md +++ b/doc/SAML-Configuration.md @@ -35,10 +35,12 @@ SimpleSAMLphp was 1.18.5. It’s possible that the names of the options will cha Open up `/home/username/simplesamlphp/config/config.php` with a text editor. `baseurlpath` + : Set this to the full path of the SimpleSAMLphp WWW directory. If you followed the above advice and created a subdomain, this should be something like `https://saml.yourdomain.com` `technicalcontact_email` + : Your email address (or anyone responsible for managing SSO integrations) `secretsalt` From 659cfefadda7246393630a5f0e508bd607ec5a2f Mon Sep 17 00:00:00 2001 From: totl Date: Tue, 12 Nov 2024 17:56:47 +0000 Subject: [PATCH 03/10] update --- doc/SAML-Configuration.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/doc/SAML-Configuration.md b/doc/SAML-Configuration.md index cec77af00..83f3f31fe 100644 --- a/doc/SAML-Configuration.md +++ b/doc/SAML-Configuration.md @@ -34,14 +34,10 @@ SimpleSAMLphp was 1.18.5. It’s possible that the names of the options will cha Open up `/home/username/simplesamlphp/config/config.php` with a text editor. -`baseurlpath` - -: Set this to the full path of the SimpleSAMLphp WWW directory. If you followed the above advice and created a +`baseurlpath` - Set this to the full path of the SimpleSAMLphp WWW directory. If you followed the above advice and created a subdomain, this should be something like `https://saml.yourdomain.com` -`technicalcontact_email` - -: Your email address (or anyone responsible for managing SSO integrations) +`technicalcontact_email` - Your email address (or anyone responsible for managing SSO integrations) `secretsalt` : Set this to any secure, random value. From be3192491fd3b10eb781f55e933e5c4ce679d299 Mon Sep 17 00:00:00 2001 From: totl Date: Tue, 12 Nov 2024 17:58:04 +0000 Subject: [PATCH 04/10] update --- doc/SAML-Configuration.md | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/doc/SAML-Configuration.md b/doc/SAML-Configuration.md index 83f3f31fe..2807a9ebd 100644 --- a/doc/SAML-Configuration.md +++ b/doc/SAML-Configuration.md @@ -39,28 +39,21 @@ subdomain, this should be something like `https://saml.yourdomain.com` `technicalcontact_email` - Your email address (or anyone responsible for managing SSO integrations) -`secretsalt` -: Set this to any secure, random value. +`secretsalt` - Set this to any secure, random value. -`auth.adminpassword` -: Set this to any secure, random value, you will use this to access the admin page of the web UI for SimpleSAML. +`auth.adminpassword` - Set this to any secure, random value, you will use this to access the admin page of the web UI for SimpleSAML. -`trusted.url.domains` -: This should be set to an array of domains that will participate in the SSO +`trusted.url.domains` - This should be set to an array of domains that will participate in the SSO handshake. I use `array(‘saml.librebooking.com’, ‘librebooking.com’)` -`session.cookie.domain` -: This should be set to the wildcard subdomain of your primary domain. For example, I use `.librebooking.com` +`session.cookie.domain` - This should be set to the wildcard subdomain of your primary domain. For example, I use `.librebooking.com` -`session.cookie.secure` -: This should be set to true, assuming all traffic is sent over https. +`session.cookie.secure` - This should be set to true, assuming all traffic is sent over https. -`store.type` -: Set this to `sql`. This ensures that PHP sessions +`store.type` - Set this to `sql`. This ensures that PHP sessions from LibreBooking and sessions from SimpleSAMLphp do not conflict. -`store.sql.dsn` -: should be set to a writable location for the sqlite database. You **must** have SQLite support in PHP enabled for this +`store.sql.dsn` - This should be set to a writable location for the sqlite database. You **must** have SQLite support in PHP enabled for this to work. Alternatively, you can set up any PDO supported database to store session data. Since I use SQLite, I have this set to something like `sqlite:/home/username/tmp/sqlitedatabase.sq3` From 4a16cd4bd4c1907618e8aabbcb48b70644f11999 Mon Sep 17 00:00:00 2001 From: totl Date: Tue, 12 Nov 2024 18:03:21 +0000 Subject: [PATCH 05/10] update --- doc/SAML-Configuration.md | 63 ++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 21 deletions(-) diff --git a/doc/SAML-Configuration.md b/doc/SAML-Configuration.md index 2807a9ebd..2be83274c 100644 --- a/doc/SAML-Configuration.md +++ b/doc/SAML-Configuration.md @@ -7,7 +7,7 @@ LibreBooking comes with multiple Single Sign On plugins out of the box. There are many benefits to SSO over standard authentication. For administrators, having a single point of account credential and access administration is very valuable. If someone leaves the organization they don’t have to deactivate accounts in multiple systems. For your normal user, the benefit is not having to register and -remember yet another set of application credentials. +remember yet another set of application credentials. In this post we’ll cover how to set up SSO with SAML. Most SSO configurations for LibreBooking are pretty straightforward – you just update the configuration options for the plugin. @@ -34,26 +34,30 @@ SimpleSAMLphp was 1.18.5. It’s possible that the names of the options will cha Open up `/home/username/simplesamlphp/config/config.php` with a text editor. -`baseurlpath` - Set this to the full path of the SimpleSAMLphp WWW directory. If you followed the above advice and created a +`baseurlpath` - Set this to the full path of the SimpleSAMLphp WWW directory. If you followed the above advice and +created a subdomain, this should be something like `https://saml.yourdomain.com` `technicalcontact_email` - Your email address (or anyone responsible for managing SSO integrations) `secretsalt` - Set this to any secure, random value. -`auth.adminpassword` - Set this to any secure, random value, you will use this to access the admin page of the web UI for SimpleSAML. +`auth.adminpassword` - Set this to any secure, random value, you will use this to access the admin page of the web UI +for SimpleSAML. `trusted.url.domains` - This should be set to an array of domains that will participate in the SSO handshake. I use `array(‘saml.librebooking.com’, ‘librebooking.com’)` -`session.cookie.domain` - This should be set to the wildcard subdomain of your primary domain. For example, I use `.librebooking.com` +`session.cookie.domain` - This should be set to the wildcard subdomain of your primary domain. For example, I +use `.librebooking.com` `session.cookie.secure` - This should be set to true, assuming all traffic is sent over https. `store.type` - Set this to `sql`. This ensures that PHP sessions from LibreBooking and sessions from SimpleSAMLphp do not conflict. -`store.sql.dsn` - This should be set to a writable location for the sqlite database. You **must** have SQLite support in PHP enabled for this +`store.sql.dsn` - This should be set to a writable location for the sqlite database. You **must** have SQLite support in +PHP enabled for this to work. Alternatively, you can set up any PDO supported database to store session data. Since I use SQLite, I have this set to something like `sqlite:/home/username/tmp/sqlitedatabase.sq3` @@ -73,13 +77,14 @@ we’ll use to finish up our configuration. browser (https://saml.librebooking.com/admin was what I used). * You’ll be prompted to enter the _auth.adminpassword_ that you set in your config.php * Click on the _Federation_ tab -* then the _XML to SimpleSAMLphp metadata converter_ link. -* Paste in the XML or, if you have it saved to a file, upload it. +* then the _XML to SimpleSAMLphp metadata converter_ link. +* Paste in the XML or, if you have it saved to a file, upload it. * SimpleSAMLphp will output at least one PHP version of that - metadata. + metadata. * For each one of those, location the file with the same name in `/home/username/simplesamlphp/metadata`. The - most common files it tells you to update will be `saml20-idp-remote.php` or `shib13-idp-remote.php` Delete everything except the - opening php tag, then paste in the output from SimpleSAMLphp. + most common files it tells you to update will be `saml20-idp-remote.php` or `shib13-idp-remote.php` Delete everything + except the + opening php tag, then paste in the output from SimpleSAMLphp. * Copy the value of the `entityid` (usually found on the 3rd line of that file) * Open up `/simplesamlphp/config/authsources.php` @@ -87,16 +92,31 @@ we’ll use to finish up our configuration. ### Update SAML Configuration in LibreBooking -Whew, almost done. The last few settings are in LibreBooking. First, open up -_/your-librebooking-directory/config/config.php_, find the authentication setting in the plugins section and set the -value to _Saml_. `$conf['settings']['plugins']['Authentication'] = 'Saml';` Open up -_/your-librebooking-directory/plugins/Authentication/Saml_ and copy _Saml.config.dist.php_ to _Saml.config.php_. Open -_Saml.config.php_ in an editor. _simplesamlphp.lib_ should be updated to the root filesystem directory of SimpleSAMLphp. -If you’re using the settings I described here, this would be _/home/username/simplesamlphp_. _simplesamlphp.config_ -should be updated to the config filesystem directory for SimpleSAMLphp. In this case -_/home/username/simplesamlphp/config_ Most of the remaining settings are attribute maps. SAML will send over user +Whew, almost done! The last few settings are in LibreBooking. + +First, open up +`/your-librebooking-directory/config/config.php` and set the authentication: + +`$conf['settings']['plugins']['Authentication'] = 'Saml';` + +Then go to the folder +`/your-librebooking-directory/plugins/Authentication/Saml` + +Then copy `Saml.config.dist.php` to `Saml.config.php`. + +Open `Saml.config.php` in an editor: + +`simplesamlphp.lib` - set this to the root filesystem directory of SimpleSAMLphp. If you’re using the settings I +described here, this would be `/home/username/simplesamlphp`. + +`simplesamlphp.config` - Set this to the config filesystem directory for SimpleSAMLphp. In this case +`/home/username/simplesamlphp/config` + +Most of the remaining settings are attribute maps. SAML will send over user attributes, but often with obscure names. LibreBooking needs to know which attribute maps to the proper user field in -LibreBooking. There are only 2 absolutely required fields to map – username/userid and email. For example, if the +LibreBooking. + +There are only 2 absolutely required fields to map – username/userid and email. For example, if the username is being sent across in the SAML payload as _urn:oid:0.1.2.3_ you’d set _simplesamlphp.username_ to this value like _$conf\[‘settings’\]\[‘simplesamlphp.username’\] = ‘urn:oid:0.1.2.3’;_ This is the same for all the other attributes. If you don’t know the attributes coming across then you can add the following line to @@ -110,9 +130,10 @@ configuration file. A couple important notes with SAML enabled: The first is that you will no longer be able to log into LibreBooking with -any other credentials. There is no “back door” – so every authentication request will be routed through SAML. +any other credentials. There is no “back door” – so every authentication request will be routed through SAML. -The other restriction is that you will not be able to use any authenticated method from the API. SAML performs a series of browser +The other restriction is that you will not be able to use any authenticated method from the API. SAML performs a series +of browser redirects in order to complete the authentication process. When using the API you are not within the context of a browser, so authentication will fail. From dbb4418c31b415d9ab34721225db831c6250f632 Mon Sep 17 00:00:00 2001 From: totl Date: Tue, 12 Nov 2024 18:05:29 +0000 Subject: [PATCH 06/10] update --- doc/SAML-Configuration.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/SAML-Configuration.md b/doc/SAML-Configuration.md index 2be83274c..4f68cde48 100644 --- a/doc/SAML-Configuration.md +++ b/doc/SAML-Configuration.md @@ -117,11 +117,13 @@ attributes, but often with obscure names. LibreBooking needs to know which attri LibreBooking. There are only 2 absolutely required fields to map – username/userid and email. For example, if the -username is being sent across in the SAML payload as _urn:oid:0.1.2.3_ you’d set _simplesamlphp.username_ to this value -like _$conf\[‘settings’\]\[‘simplesamlphp.username’\] = ‘urn:oid:0.1.2.3’;_ This is the same for all the other +username is being sent across in the SAML payload as `urn:oid:0.1.2.3` you’d set `simplesamlphp.username` to this value +like `$conf\[‘settings’\]\[‘simplesamlphp.username’\] = ‘urn:oid:0.1.2.3’;` + +This is the same for all the other attributes. If you don’t know the attributes coming across then you can add the following line to plugins/Authentication/Saml/SamlUser.php as the first line in the -constructor. `Log::Debug('Saml attributes are: %s', var_export($saml_attributes, true));` Enable Logging in LibreBooking +constructor: `Log::Debug('Saml attributes are: %s', var_export($saml_attributes, true));` Enable Logging in LibreBooking and try to log in. We’ll write out the attributes to the log file and you can copy the names into the LibreBooking SAML configuration file. From 3952e8becbf4f7bec61ab850dd205706c9981346 Mon Sep 17 00:00:00 2001 From: totl Date: Tue, 12 Nov 2024 18:06:08 +0000 Subject: [PATCH 07/10] update --- doc/SAML-Configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/SAML-Configuration.md b/doc/SAML-Configuration.md index 4f68cde48..eacbe0c11 100644 --- a/doc/SAML-Configuration.md +++ b/doc/SAML-Configuration.md @@ -118,7 +118,7 @@ LibreBooking. There are only 2 absolutely required fields to map – username/userid and email. For example, if the username is being sent across in the SAML payload as `urn:oid:0.1.2.3` you’d set `simplesamlphp.username` to this value -like `$conf\[‘settings’\]\[‘simplesamlphp.username’\] = ‘urn:oid:0.1.2.3’;` +like `$conf[‘settings][‘simplesamlphp.username’] = ‘urn:oid:0.1.2.3’;` This is the same for all the other attributes. If you don’t know the attributes coming across then you can add the following line to From 035596ef9954cf09eff5e35d8b9ad085d977e401 Mon Sep 17 00:00:00 2001 From: totl Date: Thu, 14 Nov 2024 12:44:54 +0000 Subject: [PATCH 08/10] added note on what an idp looks like. --- doc/SAML-Configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/SAML-Configuration.md b/doc/SAML-Configuration.md index eacbe0c11..8a4287de6 100644 --- a/doc/SAML-Configuration.md +++ b/doc/SAML-Configuration.md @@ -86,7 +86,7 @@ we’ll use to finish up our configuration. except the opening php tag, then paste in the output from SimpleSAMLphp. * Copy the value of the `entityid` (usually found on the 3rd - line of that file) + line of that file). It's a full URL, eg. https://sts.windows.net/1111111-1111-1111-1111-111111111111/ * Open up `/simplesamlphp/config/authsources.php` * Find the `idp` setting, and paste the value of the `entityid` there. From 235f777da3c92554479ece77eea8f8f26f8d4d93 Mon Sep 17 00:00:00 2001 From: totl Date: Thu, 14 Nov 2024 12:57:53 +0000 Subject: [PATCH 09/10] updated instructions some more --- doc/SAML-Configuration.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/doc/SAML-Configuration.md b/doc/SAML-Configuration.md index 8a4287de6..ddf170db2 100644 --- a/doc/SAML-Configuration.md +++ b/doc/SAML-Configuration.md @@ -81,14 +81,13 @@ we’ll use to finish up our configuration. * Paste in the XML or, if you have it saved to a file, upload it. * SimpleSAMLphp will output at least one PHP version of that metadata. -* For each one of those, location the file with the same name in `/home/username/simplesamlphp/metadata`. The - most common files it tells you to update will be `saml20-idp-remote.php` or `shib13-idp-remote.php` Delete everything - except the - opening php tag, then paste in the output from SimpleSAMLphp. +* For each one of those, create a file with that name plus `.php` in the folder `/home/username/simplesamlphp/metadata`. + The file should contain ` Date: Thu, 14 Nov 2024 14:36:07 +0000 Subject: [PATCH 10/10] added a reminder to copy the config.dist file --- doc/SAML-Configuration.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/SAML-Configuration.md b/doc/SAML-Configuration.md index ddf170db2..e5f18d5a6 100644 --- a/doc/SAML-Configuration.md +++ b/doc/SAML-Configuration.md @@ -32,6 +32,8 @@ Luckily, since LibreBooking is a Service Provider it doesn’t need anything spe that need to be updated individually. Please note that at the time of writing this post, the latest version of SimpleSAMLphp was 1.18.5. It’s possible that the names of the options will change in future versions. +Copy `/home/username/simplesamlphp/config/config.php.dist` to `/home/username/simplesamlphp/config/config.php` + Open up `/home/username/simplesamlphp/config/config.php` with a text editor. `baseurlpath` - Set this to the full path of the SimpleSAMLphp WWW directory. If you followed the above advice and