SimpleSAMLphp IdP
Wymagania wstępne
- Aktywny serwis ntp
- Serwer HTTP mający możliwość wykonywania skryptów PHP
- PHP w werji >= 7.1.0
- Rozszerzenia PHP:
- date, dom, hash, libxml, openssl, pcre, SPL, zlib, json, mbstring, cURL
- jeśli będziemy korzystać z bazy użytkowników LDAP: ldap
- jeśli używamy bazy danych:
- zawsze: PDO
- database driver: (mysql, pgsql, ...)
- opcjonalnie: session, memcache
Instalacja
Pobieramy najświeższą wersję SSP ze strony https://simplesamlphp.org/download
wget -O /tmp/ssp.tgz https://simplesamlphp.org/download?latest cd /usr/local tar xvf /tmp/ssp.tgz
Dostosowanie konfiguracji serwera HTTP:
- załóżmy, że nazwa naszego serwera to login.example.pl, serwer o tej nazwie należy skonfigurować jako wirtualny serwer https (port 443), zaleca się również realizację przekierowania adresu http://login.example.pl na https://login.example.pl, np:
ServerName login.example.pl DocumentRoot /var/www/html RedirectMatch 301 ^/simplesaml(.*) https://login.example.pl/simplesaml$1
- w konfiguracji serwera SSL podajemy klucz prywatny serwera (SSLCertificateKeyFile) oraz certyfikat serwera (SSLCertificateFile) i plik zawierający łańcuch certyfikatów wystawców (SSLCACertificateFile) - należy użyć znanego wystawcy certyfikatów, wymogi spełniają certyfikaty TCS, również tzw. wildcard (czyli wystawione dla nazwy *.example.pl)
- dodajemy w sekcji wirtualnego hosta SSL
Alias /simplesaml /usr/local/simplesamlphp-1.19.0/www
- nadajemy uprawnienia dla katalogu
Order allow,deny Allow from all Require all granted
(niezbędne jest Require all granted)
Konfiguracja SimpleSAMLphp IdP
Opis konfiguracji jest dostępny na stronie Konfiguracja SimpleSAMLphp IdP
Plik konfiguracyjny config/config.php
- Ustawienie baseurlpath pozostaje bez zmian, oznacza to, że serwer będzie dostępny pod adresem https://login.example.pl/simplesaml
- Na okres testów ustawiamy
'debug' => true,
oraz
'logging.level' => SimpleSAML_Logger::DEBUG,
Warto również ustawić
'logging.handler' => 'file',
zamiast logowania via syslog
- Pamiętamy o ustawieniu praw dostępu do katalogu log (zapis przez użytkownika serwera httpd).
- Dostosowujemy inne zmienne konfiguracyjne:
- auth.adminpassword - hasło administratora umożliwiające logowanie na stronie https://login.example.pl/simplesaml
- secretsalt - poprzez wygenerowanie zmiennej losowej - jej wartość w wersji produkcyjnej należy zarchiwizować, by przy aktualizacjach zagwarantować stosowanie takiej samej
- technicalcontact_name, technicalcontact_email
- timezone - należy ustalić 'Europe/Warsaw'
- enable.saml20-idp - wartość true oznacza, że instalacja pełni funkcję IdP
- Ustawiamy filtry służące do przygotowania atrybutów:
'authproc.idp' => array( 30 => 'core:LanguageAdaptor', 95 => array( 'class' => 'core:TargetedID' , 'attributename' => 'eduPersonPrincipalName', 'nameId' => TRUE), 98 => 'core:AttributeLimit', 100 => array('class' => 'core:AttributeMap', 'name2oid'), ),
- W pliku metadata/saml20-idp-hosted.php umieszczamy wykaz atrybutów, które IdP może wysłać
'attributes' => array( 'uid', 'commonName', 'sn', 'givenname', 'mail', 'eduPersonPrincipalName', 'eduPersonTargetedID' ),
Plik config/authsources.php
Zakładamy, że korzystamy z bazy LDAP do uwierzytelniania.Dostosowujemy sekcję po komentarzu Example of a LDAP authentication source - example-ldap, np:
'example-ldap' => array( 'ldap:LDAP', 'hostname' => 'localhost', 'enable_tls' => FALSE, 'debug' => FALSE, 'timeout' => 0, 'referrals' => TRUE, 'attributes' => NULL, // NULL oznacza pobierz wszystkie atrybuty, można podać tablicę atrybutóœ 'search.enable' => FALSE, 'dnpattern' => 'uid=%username%,ou=users,dc=test-org,dc=pl', 'search.base' => 'ou=users,dc=example,dc=pl', 'search.attributes' => array('uid', 'mail'), 'search.username' => 'cn=admin,dc=test-org,dc=pl', 'search.password' => '1qaz2wsx', ),
Certyfikat stosowany do podpisywania/szyfrowania danych przekazywanych między IdP a SP
Przygotowujemy certyfikat tzw. self-signed
openssl req -newkey rsa:2048 -new -x509 -days 3652 -nodes -out example.pl.pem -keyout example.pl.key
i umieszczamy klucz prywatny oraz certyfikat w katalogu cert
Uwaga! SimpleSAMLphp obsługuje wyłącznie certyfikaty RSA. Nie są wspierane certyfikaty DSA.
Plik metadata/saml20-idp-hosted.php
W pliku metadata/saml20-idp-hosted.php umieszcza się metadane IdP. Należy dostosować wpisy dotyczące certyfikatów:
'privatekey' => 'example.pl.key', 'certificate' => 'example.pl.pem',Wpis 'signature.algorithm' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
Wpis 'auth' musi wskazywać wybrane źródło uwierzytelniania, czyli np.
'auth' => 'example-ldap',Poza tym umieszczamy: 'attributes.NameFormat' => 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri',
Dodajemy ustawienie sposobu kodowania atrybutu eduPersonPrincipalName:
'attributeencodings' => array( 'urn:oid:1.3.6.1.4.1.5923.1.1.1.10' => 'raw', ),
Powiązanie z bazą danych użytkowników IdP
Patrz Baza użytkowników IdP
Moduł metarefresh - pobieranie i odświeżanie metadanych
Moduł metarefresh służy do pobierania metadanych. Jeśli współpracuje z modułem cron, to za jego pomocą można regularne aktualizować metadane. Aby aktywować moduł, wykonujemy:
cd /usr/local/simplesamlphp-1.19.0 touch modules/metarefresh/enable
Aktywizujemy również moduł cron:
touch modules/cron/enableKopiujemy pliki konfiguracyjne tych dwóch modułów do katalogu config: cp modules/cron/config-templates/module_cron.php config/ cp modules/metarefresh/config-templates/config-metarefresh.php config/
W pliku config/module_cron.php ustalamy stosowany tajny klucz (key):
'key' => '0oki8uh',
Aby metarefres regularnie pobierał metadane z określonych lokalizacji, należy dostosować plik config/config-metarefresh.php:
- Usuwamy wpis:
'kalmar' => array(.....),
- Dodajemy wpis:
'identyfikator_źródła_metadanych' => array( 'cron' => array('daily'), 'sources' => array( array( 'src' => 'URL_źródła_metadanych', 'validateFingerprint' => 'fingerprint_certyfikatu_podpisującego_metadane', ), ), 'expireAfter' => 60*60*24*4, 'outputDir' => 'metadata/katalog_tego_źródła_metadanych/', 'outputFormat' => 'flatfile', ),
Ładowanie metadanych usługodawców, z którymi ma współpracować IdP
Testowy Dostawca Usługi - PIONIER Test SP
Metadane testowego SP znajdują się pod adresem Testowy Dostawca Usługi. Metadane testowego SP w postaci "SimpleSAMLphp flat file format" umieszczmy w pliku ./metadata/saml20-sp-remote.php.
Metadane PIONIER.Id
Jeśli od razu chcemy włączyć dostęp do IdP ze wszystkich usług (SP) zarejestrowanych w eduGAIN, pomijamy poniższą instrukcję, przechodzimy do punktu Metadane PIONIER.Id-eduGAIN.IdP ma umożliwiać logowanie do federacyjnych usług zarejestrowanych w ramach PIONIER.Id. Metadane federacji PIONIER.Id są dostępne pod adresem https://aai.pionier.net.pl/pionierid.xml.IdP musi regularnie odświeżać te dane. W tym celu korzystamy z modułu metarefresh.
- Modyfikujemy plik config/config-metarefresh.php - dodajemy dane potrzebne do pobierania metadanych PIONIER.Id:
'pionierid' => array( 'cron' => array('daily'), 'sources' => array( array( 'src' => 'https://aai.pionier.net.pl/pionierid.xml', 'validateFingerprint' => '48:73:B2:14:DB:A1:48:E5:4B:F2:DA:4F:67:A5:67:E0:E1:B1:53:52', ), ), 'expireAfter' => 60*60*24*4, 'outputDir' => 'metadata/pionierid/', 'outputFormat' => 'flatfile', ),
- Tworzymy katalog metadata/pionierid/ z prawami zapisu dla użytkownika, pod którym pracuje httpd i dodajemy do crontaba wpis wg tego co podaje strona https://login.example.pl/simplesaml/module.php/cron/croninfo.php
(dostępna po zalogowaniu jako administrator), np.
00 12 * * * curl --silent "https://ssp-idp.uci.umk.pl/simplesaml/module.php/cron/cron.php?key=0oki8uh&tag=daily" > /dev/null 2>&1
Można również z tej strony uruchomić zadanie natychmiast przez kliknięcie "Run [daily]"
Zaplanowane zadanie odświeżania metadanych będzie realizowane w wyznaczonych godzinach.
- W pliku config/config.php we wpisie metadata.sources dodajemy:
array('type' => 'flatfile', 'directory' => 'metadata/pionierid'),
Metadane PIONIER.Id-eduGAIN
Jeśli IdP ma umożliwiać logowanie do usług zewnętrznych, oferowanych w ramach projektu eduGAIN, np. http://foodl.org, to należy regularnie pobierać metadane eduGAIN przygotowane przez federację PIONIER.Id. Są one dostępne pod adresem https://aai.pionier.net.pl/pionierid-edugain-sp-feed.xml.Aby włączyć regularne pobieranie metadanych wykonujemy następujące kroki:
- Dodajemy w pliku config/config-metarefresh.php wpis:
'edugain-sp' => array( 'cron' => array('hourly'), 'sources' => array( array( 'src' => 'https://aai.pionier.net.pl/pionierid-edugain-sp-feed.xml', 'validateFingerprint' => '48:73:B2:14:DB:A1:48:E5:4B:F2:DA:4F:67:A5:67:E0:E1:B1:53:52', ), ), 'expireAfter' => 60*60*24*4, // Maximum 4 days cache time. 'outputDir' => 'metadata/edugain-sp/', 'outputFormat' => 'flatfile', ),
- Tworzymy katalog metadata/edugain-sp/ z prawami zapisu dla użytkownika, pod którym pracuje httpd
- Dodajemy do crontaba wpis wg tego co podaje strona
https://login.example.pl/simplesaml/module.php/cron/croninfo.php (dostępna po zalogowaniu jako administrator), np.
10 * * * * curl --silent "https://ssp-idp.uci.umk.pl/simplesaml/module.php/cron/cron.php?key=0oki8uh&tag=daily"> /dev/null 2>&1
Można również z tej strony uruchomić zadanie natychmiast przez kliknięcie "Run [hourly]"
- Zaplanowane zadanie odświeżania metadanych będzie realizowane w wyznaczonych godzinach.
W pliku config/config.php we wpisie 'metadata.sources' należy dodać:
array('type' => 'flatfile', 'directory' => 'metadata/edugain-sp'),
Uwaga: metadane PIONIER.Id-eduGAIN zawierają metadane PIONIER.Id, należy więc wyłaczyć pobiernie metadanych PIONIER.Id, tj. wycofać zadanie icy pobierania z crontab i usunąć wpis wskazujący katalog metadata/pionierid z parameter metadata.sources w pliku config/config.php.
Włączenie modułu zgody na przekazywanie atrybutów
Aby dostawca tożsamości (IdP) wymuszał wyrażenie zgody na przekazanie atrybutów do aplikacji, musi zostać aktywowany moduł consent. W tym celu w konfiguracji głównej config/config.php, we wpisie authproc.idp odkomentowujemy:
90 => array( 'class' => 'consent:Consent', 'store' => 'consent:Cookie', 'focus' => 'yes', 'checked' => TRUE ),
Jeśli dane dotyczące zgody mają być przechowywane w bazie danych, to tworzymy w wybranej bazie tabelę:
CREATE TABLE consent ( consent_date TIMESTAMP NOT NULL, usage_date TIMESTAMP NOT NULL, hashed_user_id VARCHAR(80) NOT NULL, service_id VARCHAR(255) NOT NULL, attribute VARCHAR(80) NOT NULL, UNIQUE (hashed_user_id, service_id) );
i nadajemy uprawnienia użytkownikowi simplesaml/secreti w parametrze store zamiast 'consent:Cookie' podajemy
array( 'consent:Database', 'dsn' => 'mysql:host=localhost;dbname=consent', 'username' => 'simplesaml', 'password' => 'secret', ),
Przechowywanie identyfikatorów Persistent Id w bazie danych
Typowo identyfikatory Persistent Id są generowane każdorazowo przy korzystaniu z usługi. Ponieważ na ich wartość ma wpływ postać URL-i usługodawcy i dostawcy tożsamości, identyfikator użytkownika oraz liczba losowa (salt), która jest ustalana dla danej instalacji, wartość Persistent Id nie zmienia się dla danego dostawcy usługi i danego użytkownika. Aby zagwarantować trwałość tego identyfikatora pomiędzy instalacjami można użyć filtra o nazwie SQLPersistentId, który pozwala przechowywać identyfikatory w bazie danych (sqllite, mysql).W tym celu w głównej konfiguracji, tj. w pliku config/config.php zmieniamy wartość store.type na sql i definiujemy połączenie do bazy:
'store.type' => 'sql', 'store.sql.dsn' => 'mysql:host=localhost;dbname=ssp', 'store.sql.username' => 'ssp', 'store.sql.password' => 'zaqWSX12',Tworzymy bazę danych ssp: create database ssp;
W pliku config/config.php we wpisie authproc.idp umieszczamy:
1 => array( 'class' => 'saml:SQLPersistentNameID', 'attribute' => 'eduPersonPrincipalName', 'AllowCreate' => "true" ), 95 => array( 'class' => 'saml:PersistentNameID2TargetedID' , 'attributename' => 'eduPersonTargetedID', 'nameId' => TRUE ),
Od tej chwili w bazie danych pojawią się trzy tabele. W tabeli simpleSAMLphp_saml_PersistentNameID będzie przechowywany persistent ID.
Testowanie SimpleSAMLphp IdP
Aby przetestować działanie IdP najlepiej skorzystać z testowego dostawcy https://aai.pionier.net.pl/test/attributes.php
Metadane tego usługodawcy zostały dodane do konfiguracji (patrz Testowy Dostawca Usługi - PIONIER Test SP).
Testowy dostawca MUSI OTRZYMAĆ METADANE IdP. W tym celu należy przekazać na adres admin@aai.pionier.net.pl URL metadanych, tj. https://login.example.pl/idp/shibboleth
Dostosowanie graficzne strony logowania
Szczegółowe wskazówki jak dostosować grafikę stron SimpleSAMLphp znajdują się tutaj
Współpraca SimpleSAMLphp z innymi niż LDAP źródłami uwierzytelniania
Bazy SQL
Moduł sqlauth:SQL umożliwia uwierzytelnianie przez bazy MySQL. W pliku config/authsources.php trzeba zdefiniować parametry połączenia do bazy, np.:
'via-sql' => array( 'sqlauth:SQL', 'dsn' => 'mysql:host=localhost;port=3306;dbname=allusers', 'username' => 'admin', 'password' => '0okmnji9', 'query' => 'SELECT login,mail,eppn,displayname FROM users WHERE login=:username AND password=MD5(:password)', ),
Dokumentacja SimpleSAMLphp dotycząca użycia modułu sqlauth:SQL znajduje się na stronie https://simplesamlphp.org/docs/stable/sqlauth:sql.
Central Authentication Service (CAS)
W pakiecie SimpleSAMLphp jest dostępny moduł cas. Aby z niego korzystać, trzeba go aktywować:
cd /usr/local/simplesaml touch modules/cas/enable
Następnie w pliku config/authsources.php umieszczamy konfigurację tego modułu, która:
- wskazuje serwer CAS, sposób realizacji zalogowania, wylogowania i walidacji ticketów CAS,
- wskazuje sposób pobierania atrybutów, moduł cas zakłada, że atrybuty są dostępnie via LDAP
'example-cas' => array( 'cas:CAS', 'cas' => array( 'login' => 'https://cas.example.pl/login', 'validate' => 'https://cas.example.pl/validate', 'logout' => 'https://cas.example.pl/logout' ), 'ldap' => array( 'servers' => 'ldap://localhost', 'enable_tls' => false, 'searchbase' => 'ou=users,dc=example,dc=pl', 'searchattributes' => 'edupersonprincipalname', 'attributes' => array('edupersonprincipalname','cn', 'mail','edupersonentitlement', 'sn', 'givenname', 'edupersonaffiliation', 'edupersonscopedaffiliation', 'preferredLanguage','displayname','uid'), 'priv_user_dn' => 'cn=admin,dc=example,dc=pl', 'priv_user_pw' => '1qazxsw2', ), ),
Dokumentacja SimpleSAMLphp dotycząca użycia modułu cas znajduje się na stronie https://simplesamlphp.org/docs/stable/cas:cas