Closed freephile closed 7 months ago
✅ (we got this into the release) There's already a new simpleSAMLphp v 2.2.1 (released 5 days ago)
I added php-sodium to meet the prerequisites
See docs for Service Provider configuration https://simplesamlphp.org/docs/stable/simplesamlphp-sp.html
We used 'Mock SAML.com' as a test IdP
You may need to add a certificate and a key (info added to the authsources template) 'privatekey' => 'private.pem', 'certificate' => 'public.crt',
In LocalSettings.php, your config might look like this for MockSAML.com (details and defaults added to LocalSettings.php.j2)
$wgPluggableAuth_Config['Log in using SAML'] = [
'plugin' => 'SimpleSAMLphp',
'data' => [ 'authSourceId' => 'default-sp',
'usernameAttribute' => 'email',
'realNameAttribute' => ['firstName', 'lastName'],
'emailAttribute' => 'email'
]
];
For the saml20-idp-remote.php.j2
template which produces the file by the same name in the simplesamlphp/metadata directory, the contents can be autogenerated by the SimpleSAMLphp Admin interface tool XML to SimpleSAMLphp metadata converter (found in the 'Federation' tab at /simplesaml/admin).
For the example of mocksaml.com, copy the XML at https://mocksaml.com/api/saml/metadata, or download it from the link at https://mocksaml.com/ and then use the converter tool.
For the test case of MockSAML.com, the entire file contents would look like this: (As good as the tool is, it doesn't output the opening <?php tag, so be sure to add that!)
<?php
$metadata['https://saml.example.com/entityid'] = [
'entityid' => 'https://saml.example.com/entityid',
'contacts' => [],
'metadata-set' => 'saml20-idp-remote',
'sign.authnrequest' => true,
'SingleSignOnService' => [
[
'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
'Location' => 'https://mocksaml.com/api/saml/sso',
],
[
'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
'Location' => 'https://mocksaml.com/api/saml/sso',
],
],
'SingleLogoutService' => [],
'ArtifactResolutionService' => [],
'NameIDFormats' => [
'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
],
'keys' => [
[
'encryption' => false,
'signing' => true,
'type' => 'X509Certificate',
'X509Certificate' => 'MIIC4jCCAcoCCQC33wnybT5QZDANBgkqhkiG9w0BAQsFADAyMQswCQYDVQQGEwJVSzEPMA0GA1UECgwGQm94eUhRMRIwEAYDVQQDDAlNb2NrIFNBTUwwIBcNMjIwMjI4MjE0NjM4WhgPMzAyMTA3MDEyMTQ2MzhaMDIxCzAJBgNVBAYTAlVLMQ8wDQYDVQQKDAZCb3h5SFExEjAQBgNVBAMMCU1vY2sgU0FNTDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALGfYettMsct1T6tVUwTudNJH5Pnb9GGnkXi9Zw/e6x45DD0RuRONbFlJ2T4RjAE/uG+AjXxXQ8o2SZfb9+GgmCHuTJFNgHoZ1nFVXCmb/Hg8Hpd4vOAGXndixaReOiq3EH5XvpMjMkJ3+8+9VYMzMZOjkgQtAqO36eAFFfNKX7dTj3VpwLkvz6/KFCq8OAwY+AUi4eZm5J57D31GzjHwfjH9WTeX0MyndmnNB1qV75qQR3b2/W5sGHRv+9AarggJkF+ptUkXoLtVA51wcfYm6hILptpde5FQC8RWY1YrswBWAEZNfyrR4JeSweElNHg4NVOs4TwGjOPwWGqzTfgTlECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAAYRlYflSXAWoZpFfwNiCQVE5d9zZ0DPzNdWhAybXcTyMf0z5mDf6FWBW5Gyoi9u3EMEDnzLcJNkwJAAc39Apa4I2/tml+Jy29dk8bTyX6m93ngmCgdLh5Za4khuU3AM3L63g7VexCuO7kwkjh/+LqdcIXsVGO6XDfu2QOs1Xpe9zIzLpwm/RNYeXUjbSj5ce/jekpAw7qyVVL4xOyh8AtUW1ek3wIw1MJvEgEPt0d16oshWJpoS1OT8Lr/22SvYEo3EmSGdTVGgk3x3s+A0qWAqTcyjr7Q4s/GKYRFfomGwz0TZ4Iw1ZN99Mm0eo2USlSRTVl7QHRTuiuSThHpLKQQ==',
],
],
];
saml20-idp-remote
looks like this when generated by the simplesamlphp library's Admin Interface conversion tool (simplesaml/module.php/admin/federation/metadata-converter#converted)
$metadata['https://saml.example.com/entityid'] = [
'entityid' => 'https://saml.example.com/entityid',
'contacts' => [],
'metadata-set' => 'saml20-idp-remote',
'sign.authnrequest' => true,
'SingleSignOnService' => [
[
'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
'Location' => 'https://mocksaml.com/api/saml/sso',
],
[
'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
'Location' => 'https://mocksaml.com/api/saml/sso',
],
],
'SingleLogoutService' => [],
'ArtifactResolutionService' => [],
'NameIDFormats' => [
'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
],
'keys' => [
[
'encryption' => false,
'signing' => true,
'type' => 'X509Certificate',
'X509Certificate' => 'MIIC4jCCAcoCCQC33wnybT5QZDANBgkqhkiG9w0BAQsFADAyMQswCQYDVQQGEwJVSzEPMA0GA1UECgwGQm94eUhRMRIwEAYDVQQDDAlNb2NrIFNBTUwwIBcNMjIwMjI4MjE0NjM4WhgPMzAyMTA3MDEyMTQ2MzhaMDIxCzAJBgNVBAYTAlVLMQ8wDQYDVQQKDAZCb3h5SFExEjAQBgNVBAMMCU1vY2sgU0FNTDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALGfYettMsct1T6tVUwTudNJH5Pnb9GGnkXi9Zw/e6x45DD0RuRONbFlJ2T4RjAE/uG+AjXxXQ8o2SZfb9+GgmCHuTJFNgHoZ1nFVXCmb/Hg8Hpd4vOAGXndixaReOiq3EH5XvpMjMkJ3+8+9VYMzMZOjkgQtAqO36eAFFfNKX7dTj3VpwLkvz6/KFCq8OAwY+AUi4eZm5J57D31GzjHwfjH9WTeX0MyndmnNB1qV75qQR3b2/W5sGHRv+9AarggJkF+ptUkXoLtVA51wcfYm6hILptpde5FQC8RWY1YrswBWAEZNfyrR4JeSweElNHg4NVOs4TwGjOPwWGqzTfgTlECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAAYRlYflSXAWoZpFfwNiCQVE5d9zZ0DPzNdWhAybXcTyMf0z5mDf6FWBW5Gyoi9u3EMEDnzLcJNkwJAAc39Apa4I2/tml+Jy29dk8bTyX6m93ngmCgdLh5Za4khuU3AM3L63g7VexCuO7kwkjh/+LqdcIXsVGO6XDfu2QOs1Xpe9zIzLpwm/RNYeXUjbSj5ce/jekpAw7qyVVL4xOyh8AtUW1ek3wIw1MJvEgEPt0d16oshWJpoS1OT8Lr/22SvYEo3EmSGdTVGgk3x3s+A0qWAqTcyjr7Q4s/GKYRFfomGwz0TZ4Iw1ZN99Mm0eo2USlSRTVl7QHRTuiuSThHpLKQQ==',
],
],
];
whereas Meza's template driven version looks like this:
Not far off. Notice 'certData' used by Meza instead of "X509Certificate" - It works, but I didn't look into the details of the expected/accepted schema.
<?php
/**
* SAML 2.0 remote IdP metadata for SimpleSAMLphp.
*
* Remember to remove the IdPs you don't use from this file.
*
* See: https://simplesamlphp.org/docs/stable/simplesamlphp-reference-idp-remote
*/
$metadata['https://saml.example.com/entityid'] =
[
'SingleSignOnService' => 'https://mocksaml.com/api/saml/sso',
'SingleLogoutService' => 'https://mocksaml.com/api/saml/sso',
'certData' => 'MIIC4jCCAcoCCQC33wnybT5QZDANBgkqhkiG9w0BAQsFADAyMQswCQYDVQQGEwJVSzEPMA0GA1UECgwGQm94eUhRMRIwEAYDVQQDDAlNb2NrIFNBTUwwIBcNMjIwMjI4MjE0NjM4WhgPMzAyMTA3MDEyMTQ2MzhaMDIxCzAJBgNVBAYTAlVLMQ8wDQYDVQQKDAZCb3h5SFExEjAQBgNVBAMMCU1vY2sgU0FNTDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALGfYettMsct1T6tVUwTudNJH5Pnb9GGnkXi9Zw/e6x45DD0RuRONbFlJ2T4RjAE/uG+AjXxXQ8o2SZfb9+GgmCHuTJFNgHoZ1nFVXCmb/Hg8Hpd4vOAGXndixaReOiq3EH5XvpMjMkJ3+8+9VYMzMZOjkgQtAqO36eAFFfNKX7dTj3VpwLkvz6/KFCq8OAwY+AUi4eZm5J57D31GzjHwfjH9WTeX0MyndmnNB1qV75qQR3b2/W5sGHRv+9AarggJkF+ptUkXoLtVA51wcfYm6hILptpde5FQC8RWY1YrswBWAEZNfyrR4JeSweElNHg4NVOs4TwGjOPwWGqzTfgTlECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAAYRlYflSXAWoZpFfwNiCQVE5d9zZ0DPzNdWhAybXcTyMf0z5mDf6FWBW5Gyoi9u3EMEDnzLcJNkwJAAc39Apa4I2/tml+Jy29dk8bTyX6m93ngmCgdLh5Za4khuU3AM3L63g7VexCuO7kwkjh/+LqdcIXsVGO6XDfu2QOs1Xpe9zIzLpwm/RNYeXUjbSj5ce/jekpAw7qyVVL4xOyh8AtUW1ek3wIw1MJvEgEPt0d16oshWJpoS1OT8Lr/22SvYEo3EmSGdTVGgk3x3s+A0qWAqTcyjr7Q4s/GKYRFfomGwz0TZ4Iw1ZN99Mm0eo2USlSRTVl7QHRTuiuSThHpLKQQ==',
];
SimpleSAMLphp's metadata conversion tool SHOULD be used to interrogate your IdP's published metadata for values that go into Meza's public.yml file
secret.yml
---
wiki_app_fqdn: "134.209.163.205"
# The rest of the contents of this file have been omitted to focus on just the SAML related parts
#### Setup the SECRET configuration for SAML Authentication
#### Instructions at https://www.mediawiki.org/wiki/Meza/Setup_SAML_authentication
#### The mere presence of this key puts your Meza into "SAML Auth" mode
#### As of Meza 35.5.0 there is no 'undo' to get back to 'regular' Auth
#### So, only use this on a dev or test environment where you can verify it
#### before adopting it.
saml_secret:
# A crypto salt for randomness. This should be random and unique. Use the
# command below to generate a 32-character random string
# tr -c -d '0-9a-zA-Z' </dev/urandom | dd bs=32 count=1 2>/dev/null;echo
salt: zmxXmsatuLTrBYDN7qTAS4Qbw5Nhyp4G
# A password to enter the SimpleSamlPhp web interface. Optionally use the
# 16-character random generator below:
# tr -c -d '0-9a-zA-Z' </dev/urandom | dd bs=16 count=1 2>/dev/null;echo
adminpassword: worldwidewiki
public.yml
---
# Config file for putting non-secure items needed for configuration during
# deploy of the application
## The other contents of this file have been removed to focus
## on just the SAML Auth aspects
## Setup the PUBLIC configuration for SAML Authentication
## Instructions at https://www.mediawiki.org/wiki/Meza/Setup_SAML_authentication
## The mere presence of this key puts your Meza into "SAML Auth" mode
## As of Meza 35.5.0 there is no 'undo' to get back to 'regular' Auth
## So, only use this on a dev or test environment where you can verify it
## before adopting it.
saml_public:
# SAML attribute provided by IdP (Identity Provider)
idp_username_attr: email
# SAML attribute provided by IdP
idp_realname_attr: ['firstName', 'lastName']
# SAML attribute provided by IdP
idp_email_attr: email
# SP (service provider) Entity ID, which should be the fully qualified
# domain name of your application
sp_entity_id: "{{ wiki_app_fqdn }}"
# The format of the NameID we request from this IdP
# MockSAML.com can use (unset) defaults
# When the entire option or either array key is unset, the defaults are
# transient and true respectively
# name_id_policy: [ 'Format' => persistent, 'AllowCreate' => true ]
# name_id_policy: "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
# IdP (identity provider) Entity URL. Used as a unique identifier in
# config/authsources.php
# also used in metadata/saml20-idp-remote.php
idp_entity_id: https://saml.example.com/entityid
# URL of your SAML signon service
single_sign_on_service: https://mocksaml.com/api/saml/sso
# URL of your SAML logout service. Use signon if you don't have one.
single_logout_service: https://mocksaml.com/api/saml/sso
# Contact info for issues with SAML
technicalcontact_name: Administrator
technicalcontact_email: greg.rundlett@gmail.com
# The PUBLIC certificate of your Identity Provider
cert_data: >
'MIIC4jCCAcoCCQC33wnybT5QZDANBgkqhkiG9w0BAQsFADAyMQswCQYDVQQGEwJVSzEPMA0GA1UECgwGQm94eUhRMRIwEAYDVQQDDAlNb2NrIFNBTUwwIBcNMjIwMjI4MjE0NjM4WhgPMzAyMTA3MDEyMTQ2MzhaMDIxCzAJBgNVBAYTAlVLMQ8wDQYDVQQKDAZCb3h5SFExEjAQBgNVBAMMCU1vY2sgU0FNTDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALGfYettMsct1T6tVUwTudNJH5Pnb9GGnkXi9Zw/e6x45DD0RuRONbFlJ2T4RjAE/uG+AjXxXQ8o2SZfb9+GgmCHuTJFNgHoZ1nFVXCmb/Hg8Hpd4vOAGXndixaReOiq3EH5XvpMjMkJ3+8+9VYMzMZOjkgQtAqO36eAFFfNKX7dTj3VpwLkvz6/KFCq8OAwY+AUi4eZm5J57D31GzjHwfjH9WTeX0MyndmnNB1qV75qQR3b2/W5sGHRv+9AarggJkF+ptUkXoLtVA51wcfYm6hILptpde5FQC8RWY1YrswBWAEZNfyrR4JeSweElNHg4NVOs4TwGjOPwWGqzTfgTlECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAAYRlYflSXAWoZpFfwNiCQVE5d9zZ0DPzNdWhAybXcTyMf0z5mDf6FWBW5Gyoi9u3EMEDnzLcJNkwJAAc39Apa4I2/tml+Jy29dk8bTyX6m93ngmCgdLh5Za4khuU3AM3L63g7VexCuO7kwkjh/+LqdcIXsVGO6XDfu2QOs1Xpe9zIzLpwm/RNYeXUjbSj5ce/jekpAw7qyVVL4xOyh8AtUW1ek3wIw1MJvEgEPt0d16oshWJpoS1OT8Lr/22SvYEo3EmSGdTVGgk3x3s+A0qWAqTcyjr7Q4s/GKYRFfomGwz0TZ4Iw1ZN99Mm0eo2USlSRTVl7QHRTuiuSThHpLKQQ=='
Rather than scatter instructions and templates and code between mediawiki.org and meza for accomplishing SAML Authentication in Meza, the default templates that are laid down when you first run 'getmeza.sh' should be updated to contain (commented) example sections for enabling SAML auth.
e.g. src/roles/init-controller-config/templates/public.yml.j2
Meza uses a special setup for SAML authentication. Rather than put it into 'core' extensions and handle it like any other set of MediaWiki extensions, the instructions have you put configs into 'secret' and 'public' sections, and deploy. The deploy detects these configurations and ensures installation of extension:PluggableAuth as well as extension:SimpleSAMLPhp and the underlying simpleSAMLphp library.
And, the SAML authentication is used or leveraged beyond just the MediaWiki app to encompass the whole Webserver (Apache and HAProxy load balancer), so you'll find a class to extend simpleSAMLPhp
src/roles/saml/templates/NonMediaWikiSimpleSamlAuth.php.j2
The requirements for SAML authentication for MediaWiki 1.39 mean upgrading the whole stack: