Shibboleth IdP - wersja 3

Z PIONIER.Id
Przejdź do nawigacji Przejdź do wyszukiwania
Wersja do druku nie jest już wspierana i może powodować błędy w wyświetlaniu. Zaktualizuj swoje zakładki i zamiast funkcji strony do druku użyj domyślnej funkcji drukowania w swojej przeglądarce.


Instalacja Shibboleth IdP 3.X

Bieżącą stabilną wersją jest V3.4.3

Wymagania wstępne:

Pobieramy najnowszą wersję Shibboleth IdP ze strony https://shibboleth.net/downloads/identity-provider/latest/ (proszę dostosować nazwę pliku po sprawdzeniu aktualnej wersji), przykładowo:

cd /opt/
wget https://shibboleth.net/downloads/identity-provider/latest/shibboleth-identity-provider-3.4.3.tar.gz
tar zxfv shibboleth-identity-provider-3.4.3.tar.gz

Pobieramy wymienione wyżej pakiety mysql, commons, HikariCP , BoneCP oraz cas-client-core.

Tworzymy katalog /opt/shibboleth-idp/edit-webapp/, a w nim podkatalog WEB-INF/lib/, w którym umieszczamy pliki jar pobranych pakietów dodatkowych.

W podkatalogu system/messages/ dystrybucji umieszczamy pliki z wersją polską i angielską komunikatów:

Uruchamiamy instalację pakietu:

./bin/install.sh Wskazujemy parametry instalacyjne:
Source (Distribution) Directory: [/opt/shibboleth-identity-provider-3.4.3] podajemy katalog dystrybucji
Installation Directory: [/opt/shibboleth-idp] podajemy katalog instalacji
Hostname: [host.example.pl] idp.example.pl podajemy nazwę serwera
SAML EntityID: [1] zatwierdzamy nazwę SAML tworzonego elementu 
Attribute Scope: [example.pl] example.pl podajemy dla jakiej domeny będzie działał IdP
TLS Private Key Password: podajemy hasło klucza prywatnego
Re-enter password: ponownie wprowadzamy powyższe hasło
Cookie Encryption Key Password: podajemy hasło do szyfrowania cookies
Re-enter password: ponownie wprowadzamy powyższe hasło

W czasie instalacji tworzony jest katalog instalacyjny, kopiowana jest konfiguracja domyślna, w katalogu katalog /opt/shibboleth-idp/credentials/ umieszczane są wygenerowane klucze podpisujący i szyfrujący, klucz do komunikacji typu back-channel oraz magazyn typu JCEKS zabezpieczający cookies. Powstaje również plik aplikacji idp.war. Klucz podpisujący (pliki idp-signing.*) jest stosowany do podpisywania odpowiedzi wysyłanych przez IdP, klucza szyfrującego (pliki idp-encryption.*) IdP używa do zaszyfrowania danych przekazywanych w odpowiedzi.

Magazyn idp-backchannel jest przygotowywany do zabezpieczenia komunikacji SSL realizowanej w tzw. kanale tylnym (backchannel), tj. komunikacji między dostawcą usługi a IdP bez pośrednictwa przeglądarki.

Aby utworzony plik aplikacji zawierał wszystkie dodatkowe biblioteki, wykonujemy ponowne utworzenie aplikacji (zostaną uwzględnione biblioteki umieszczone w podkatalogu edit-webapp/)

cd /opt/shibboleth-idp/
./bin/build.sh

Definiujemy usługę shibboleth-idp w kontenerze tomcat. Poniższe instrukcje zakładają, że pliki konfiguracyjne tomcata znajdują się w /etc/tomcat, a użytkownik i grupa procesu to tomcat. W zależności od wersji systemu operacyjnego czy tomcata, może to być katalog /etc/tomcat7 i użytkownik/grupa tomcat7. Tworzymy plik /etc/tomcat/Catalina/localhost/idp.xml z następującą zawartością

 
<Context docBase="/opt/shibboleth-idp/war/idp.war"
    privileged="true"
    antiResourceLocking="false"
    antiJARLocking="false"
    unpackWAR="false"
    swallowOutput="true" />

W pliku konfiguracyjny tomcata /etc/tomcat/server.xml edytujemy definicję elementu Connector dla portu 8009:

<Connector port="8009" enableLookups="false" redirectPort="8443" protocol="AJP/1.3"
request.tomcatAuthentication="false" address="127.0.0.1" />

Ustalamy prawa własności katalogów logów oraz metadanych:

chown tomcat:tomcat /opt/shibboleth-idp/logs/
chown tomcat:tomcat /opt/shibboleth-idp/metadata/

i restartujemy serwis tomcat

W konfiguracji httpd definiujemy korzystanie z proxy_ajp

echo 'ProxyPass /idp/ ajp://localhost:8009/idp/' > /etc/httpd/conf.d/proxy_ajp.conf

Konfigurujemy usługę https - certyfikat używany do połączenia musi być poświadczony przez ogólnie znane CA (np. TCS).

Restartujemy serwis httpd

Konfiguracja kontenera tomcat na potrzeby obsługi back-channel jest następująca:

  • należy pobrać ze strony projektu Shibboleth wtyczkę do obsługi SSL tego typu kanału: plugin
  • w pliku konfiguracyjnym TOMCAT_HOME/conf/server.xml umieszczmy:
 
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
    maxThreads="150"
    SSLEnabled="true"
    scheme="https"
    secure="true"
    clientAuth="want"
    keystoreFile="/opt/shibboleth-idp/credentials/idp-backchannel.p12"
    keystorePass="hasło ustalone dla magazynu w trakcie instalacji, podane w odpowiedzi TLS Private Key Password"
    keystoreType="PKCS12"
    trustManagerClassName="net.shibboleth.utilities.ssl.TrustAnyCertificate" />

W części Instalacja Jetty przedstawiono przygotowanie kontenera Jetty do obsługi Shibboleth IdP. Konfigurację IdP działającego w kontenerze Jetty do tych potrzeb back-channel w ramach części dotyczącej instalacji Jetty Obsługa back-channel.

Oprogramowanie IdP MUSI być udostępniane za pomocą bezpiecznego połączenia SSL/TLS, czyli poprzez protokół https. Serwer udostępniający IdP musi być chroniony certyfikatem wystawionym przez urząd, któremu użytkownik będzie mógł ufać, czyli np. certyfikatem TCS. Jeśli używanym kontenerem jest tomcat z apache'm, wówczas certyfikat serwera należy umieścić w konfiguracji apache. Jeśli kontenerem jest jetty, to certyfikat serwera musi zostać przekształcony do odpowiedniej postaci (patrz Instalacja Jetty).

Konfiguracja Shibboleth IdP 3.X

Pliki konfiguracyjne Shibboleth 3 IdP są umieszczone w katalogu /opt/shibboleth-idp/conf. W katalogu /opt/shibboleth-idp/credentials są umieszczane certyfikaty, klucze i inne dane związane z uwierzytelnianiem. W katalogu /opt/shibboleth-idp/metadata lokalizowane są metadane SAML. Na stronie https://wiki.shibboleth.net/confluence/display/IDP30/Configuration#Configuration-InstallationLayout została opisana rola poszczególnych podkatalogów w drzewie instalacji Shibboleth.

Dostosowanie plików konfiguracyjnych

W wersji 3 wprowadzono nową postać konfiguracji - za pomocą plików o formacie properties w Javie. W tych plikach umieszczane są najistotniejsze ustawienia. Pliki o formacie XML pozostały do utrzymywania bardziej zaawansowanych aspektów konfiguracji. Podstawowe pliki konfiguracyjne to:

idp.properties

W tym pliku podczas instalacji są wpisywane ścieżki do certyfikatów, hasła do plików z kluczami, nazwa IdP itp.Podczas pierwszego uruchomienia IdP nie są potrzebne żadne zmiany w tym plik. Zmiany będą potrzebne np. przy ustalaniu zasad działania modułu wyrażania zgody na przekazanie atrybutów.

relying-party.xml

Plik ten zawiera definicje sposobu działania IdP, ustala wspierane profile oraz umożliwia zrządzanie ustawieniami w ramach profili.Modyfikacje pliku mogą być potrzebne w przypadku, gdy np. rezygnujemy w przypadku konkretnych dostawców usług z pytania o zgodę na przekazywanie atrybutów.

metadata-providers.xml

Plik ten zawiera konfigurację metadanych, z których korzysta IdP. W wersji 2 wskazanie metadanych było zlokalizowane w pliku relying-party.xml.Sposób definicji metadanych jest taki sam. Domyślnie w pliku nie są umieszczone żadne wskazania metadanych. Aby sprawdzić działanie IdP z aplikacją testową PIONIER.Id należy dodać w tym pliku:

<!-- PIONIER.Id Test SP -->
<MetadataProvider id="TESTSP" xsi:type="FileBackedHTTPMetadataProvider"
  metadataURL="https://aai.pionier.net.pl/test/module.php/saml/sp/metadata.php/default-sp"
  backingFile="/opt/shibboleth-idp/metadata/testsp.xml">
</MetadataProvider>
<!-- PIONIER.Id Test SP -->

Aby IdP współpracował ze wszystkimi SP zarejestrowanymi w eduGAIN dodajemy:

 
<MetadataProvider id="eduGAINSP" xsi:type="FileBackedHTTPMetadataProvider"
  metadataURL="http://aai.pionier.net.pl/pionierid-edugain-sp-feed.xml"
  backingFile="/opt/shibboleth-idp/metadata/pionierid-edugain-sp-feed.xml">
 <MetadataFilter xsi:type="SignatureValidation" certificateFile="${idp.home}/credentials/pionier-signer.pem"/>
</MetadataProvider>

a w pliku opt/shibboleth-idp/credentials/pionier-signer.pem umieszczamy zawartość pobraną z adresu https://aai.pionier.net.pl/PIONIER.Id.pem

Shibboleth IdP domyślnie odświeża wszystkie metadane co 3 godziny.

saml-nameid.properties

W tym pliku są ustalane zasady generowania identyfikatora NameID.Domyślną postacią identyfikatora jest urn:oasis:names:tc:SAML:2.0:nameid-format:transient.Jeśli IdP ma zawsze generować identyfikator typu persistent to należy wpisać w pliku:

idp.nameid.saml2.default = urn:oasis:names:tc:SAML:2.0:nameid-format:persistent

Aby IdP zapisywał identyfikatory do bazy danych, należy umieścić w pliku:

idp.persistentId.generator = shibboleth.StoredPersistentIdGenerator
idp.persistentId.store = IdPPersistentIdStore
idp.persistentId.sourceAttribute = eduPersonPrincipalName
idp.persistentId.salt = wartość_losowa_używana_do_wyliczenia_persistentId

Parametr idp.persistentId.generator ustala, że identyfikator persistenId ma być generowany za pomocą klasy umożliwiającej jego zapamiętanie. Parametr idp.persistentId.store wskazuje nazwę magazynu do przechowywania identyfikatorów, sposób obsługi tego magazynu jest definiowany w pliku konfiguracyjnym saml-nameid.xml. Parametr idp.persistentId.sourceAttribute zawiera atrybut używany do wyliczania wartości persistentId.

saml-nameid.xml

W pliku są definiowane działania w celu wygenerowania identyfikatora persistentId. Jeśli w pliku saml-nameid.properties wskazano idp.persistentId.store, to w tym pliku należy:

  • odkomentować bean="shibboleth.SAML2PersistentGenerator", tak by blok o id="shibboleth.SAML2NameIDGenerators" był następujący:
 <util:list id="shibboleth.SAML2NameIDGenerators">
        <ref bean="shibboleth.SAML2TransientGenerator" />
        <ref bean="shibboleth.SAML2PersistentGenerator" />
    </util:list>
  • zdefiniować IdPPersistentIdStore, np.:
<bean id="IdPPersistentIdStore" class="net.shibboleth.idp.saml.nameid.impl.JDBCPersistentIdStore">
    <property name="dataSource">
        <bean class="org.apache.commons.dbcp2.BasicDataSource"
            p:driverClassName="com.mysql.jdbc.Driver"
            p:url="jdbc:mysql://localhost:3306/shibboleth"
            p:username="użytkownik"
            p:password="hasło użytkownika"
            p:maxTotal="10"
            p:maxIdle="5"
            p:maxWaitMillis="15000"
            p:testOnBorrow="true"
            p:validationQuery="select 1"
            p:validationQueryTimeout="5" />
    </property>
</bean> 

shibboleth.StoredPersistentIdGenerator używa tablicy shibpid we wskazanej powyżej bazie danych do zapisywania identyfikatorów. Należy stworzyć tablicę:

CREATE TABLE shibpid (
    localEntity text NOT NULL,
    peerEntity text NOT NULL,
    principalName VARCHAR(255) NOT NULL default '',
    localId VARCHAR(255) NOT NULL,
    persistentId VARCHAR(50) NOT NULL,
    peerProvidedId VARCHAR(255) NULL,
    creationDate TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ,
    deactivationDate TIMESTAMP NULL DEFAULT NULL,
    KEY `persistentId` (`persistentId`),
    KEY `persistentId_2` (`persistentId`,`deactivationDate`),
    KEY `localEntity` (`localEntity`(16),`peerEntity`(16),`localId`),
    KEY `localEntity_2` (`localEntity`(16),`peerEntity`(16),`localId`,`deactivationDate`)
);
attribute-resolver.xml

W tym pliku jest ustalany sposób tworzenia atrybutów oraz ich kodowania przed wysłaniem.Atrybuty są definiowane w blokach resolver:AttributeDefinition, np.

 
<AttributeDefinition id="eduPersonPrincipalName" xsi:type="Scoped" scope="%{idp.scope}" sourceAttributeID="uid">
 <Dependency ref="myLDAP" />
 <AttributeEncoder xsi:type="SAML1ScopedString"
   name="urn:mace:dir:attribute-def:eduPersonPrincipalName" encodeType="false" />
 <AttributeEncoder xsi:type="SAML2ScopedString"
   name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" friendlyName="eduPersonPrincipalName" encodeType="false" />
</AttributeDefinition>
<AttributeDefinition id="uid" xsi:type="Simple" sourceAttributeID="uid">
 <Dependency ref="myLDAP"/>
 <AttributeEncoder xsi:type="SAML1String"
    name="urn:mace:dir:attribute-def:uid" encodeType="false" />
 <AttributeEncoder xsi:type="SAML2String"
    name="urn:oid:0.9.2342.19200300.100.1.1" friendlyName="uid" encodeType="false" />
</AttributeDefinition>

Pierwsza z powyższych definicji ustala, że atrybut eduPersonPrincipalName, który jest w schemacie eduPerson traktowany jako identyfikator użytkownika, powstaje na bazie atrybutu uid i jest atrybutem typu Scoped, co oznacza, że powstaje poprzez dodanie do wartości atrybutu uid domeny zadeklarowanej w pliku idp.properties jako idp.scope.

Druga definicja precyzuje zasady otrzymania atrybutu uid - jest on pobierany z bazy wskazanej w elemencie resolverDependency.

Na potrzeby generowania przez IdP stałych identyfikatorów związanych z konkretnym dostawcą usługi (SP), należy zdefiniować atrybut edupersonTargetedID, np. jako atrybut powiązany z tzw. trwałym identyfikatorem:

<AttributeDefinition id="eduPersonTargetedID" xsi:type="SAML2NameID"
    nameIdFormat="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
    sourceAttributeID="persistentId">
  <resolver:Dependency ref="StoredId" />
  <resolver:AttributeEncoder xsi:type="SAML1XMLObject" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" />
  <resolver:AttributeEncoder xsi:type="SAML2XMLObject" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" 
    friendlyName="eduPersonTargetedID" />
</AttributeDefinition>

Powiązania atrybutów z bazą danych są definiowane w elementach , np.

 
<DataConnector id="myLDAP" xsi:type="LDAPDirectory"
        ldapURL="ldap://localhost"
        baseDN="ou=users,dc=test-org,dc=pl"
        principal="cn=admin,dc=test-org,dc=pl"
        principalCredential="hasło użytkownika admin">
        <FilterTemplate>
            <![CDATA[
                (uid=$requestContext.principalName)
            ]]>
        </FilterTemplate>
</DataConnector>

Z kolei w elemencie o identyfikatorze StoredId wskazujemy parametry bazy danych służącej do przechowywania tego identyfikatora , np.:

<DataConnector xsi:type="StoredId" 
 id="StoredId"
 sourceAttributeID="%{idp.persistentId.sourceAttribute}"
 generatedAttributeID="persistentId"
 salt="%{idp.persistentId.salt}">
  <resolver:Dependency ref="myLDAP" />
  <ApplicationManagedConnection
    jdbcDriver="com.mysql.jdbc.Driver"
    jdbcURL="jdbc:mysql://localhost:3306/shibboleth?autoReconnect=true"
    jdbcUserName="shibboleth"
    jdbcPassword="hasło jdbsUserName" />
</DataConnector>
 

Powyższa definicja ustala źródłowy atrybut, nazwę wygenerowanego atrybutu oraz powiązania z bazą danych.

Pobierz wzorcowy plik attribute-resolver.xml

attribute-filter.xml

Zawiera ustalenia dotyczące filtrowania atrybutów na podstawie nazw atrybutów, ich wartości. Umożliwia precyzyjną kontrolę dostępu poprzez wskazanie dozwolonych odbiorców atrybutów.


IdP powinien przekazywać każdemu dostawcy usługi takie atrybuty jak transientId, persistentId, edupersonTargetedID:

 
<AttributeFilterPolicy id="releaseTransientIdToAnyone">
   <PolicyRequirementRule xsi:type="ANY"/>
   <AttributeRule attributeID="transientId">
     <PermitValueRule xsi:type="ANY"/>
   </AttributeRule>
</AttributeFilterPolicy
     
<AttributeFilterPolicy id="releasePersistentIdToAnyone">
   <PolicyRequirementRule xsi:type="ANY"/>
   <AttributeRule attributeID="persistentId">
     <PermitValueRule xsi:type="ANY" />
   </AttributeRule>
</AttributeFilterPolicy>
 
<AttributeFilterPolicy id="releasePermanentIdToAnyone">
   <PolicyRequirementRule xsi:type="ANY"/>
   <AttributeRule attributeID="eduPersonTargetedID">
     <PermitValueRule xsi:type="ANY"/>
   </AttributeRule>
</AttributeFilterPolicy>

Jeśli IdP ma przekazywać konkretne atrybuty określonemu SP, to można umieścić poniższą regułę:

<AttributeFilterPolicy id="releaseeduPersonEntitlementtosp12example">
        <PolicyRequirementRule xsi:type="OR">
            <Rule xsi:type="AttributeRequesterString"
                        value="" />
            <Rule xsi:type="AttributeRequesterString"
                        value="https://sp2.example.pl" />
        </PolicyRequirementRule>
        <AttributeRule attributeID="eduPersonEntitlement">
            <PermitValueRule xsi:type="ANY" />
        </AttributeRule>
</AttributeFilterPolicy>

która ustala, że atrybut eduPersonEntitlement będzie przekazywany do usług https://sp1.example.pl i https://sp2.example.pl.

Dostawcy tożsamości zarejestrowani w PIONIER.Id powinni akceptować Geant Code of Conduct (http://www.geant.net/uri/dataprotection-code-of-conduct/v1) oraz kategorię SP research and scholarship (http://refeds.org/category/research-and-scholarship). Odpowiadają za to poniższe reguły:

 
    <AttributeFilterPolicy id="releaseToCoC">
        <PolicyRequirementRule xsi:type="EntityAttributeExactMatch"
            attributeName="http://macedir.org/entity-category"
            attributeValue="http://www.geant.net/uri/dataprotection-code-of-conduct/v1"/>
        <AttributeRule attributeID="displayName">
            <PermitValueRule xsi:type="MappedAttributeInMetadata" onlyIfRequired="true"/>
        </AttributeRule>
        <AttributeRule attributeID="sn">
            <PermitValueRule xsi:type="MappedAttributeInMetadata" onlyIfRequired="true"/>
        </AttributeRule>
        <AttributeRule attributeID="mail">
            <PermitValueRule xsi:type="MappedAttributeInMetadata" onlyIfRequired="true"/>
        </AttributeRule>
        <AttributeRule attributeID="eduPersonPrincipalName">
            <PermitValueRule xsi:type="MappedAttributeInMetadata" onlyIfRequired="true"/>
        </AttributeRule>
        <AttributeRule attributeID="eduPersonScopedAffiliation">
            <PermitValueRule xsi:type="MappedAttributeInMetadata" onlyIfRequired="true"/>
        </AttributeRule>
    </AttributeFilterPolicy>
    <AttributeFilterPolicy id="releaseToRRandS">
        <PolicyRequirementRule xsi:type="EntityAttributeExactMatch"
            attributeName="http://macedir.org/entity-category"
            attributeValue="http://refeds.org/category/research-and-scholarship"/>
        <AttributeRule attributeID="displayName">
            <PermitValueRule xsi:type="ANY"/>
        </AttributeRule>
        <AttributeRule attributeID="sn">
            <PermitValueRule xsi:type="ANY"/>
        </AttributeRule>
        <AttributeRule attributeID="givenName">
            <PermitValueRule xsi:type="ANY"/>
        </AttributeRule>
        <AttributeRule attributeID="mail">
            <PermitValueRule xsi:type="ANY"/>
        </AttributeRule>
        <AttributeRule attributeID="eduPersonPrincipalName">
            <PermitValueRule xsi:type="ANY"/>
        </AttributeRule>
        <AttributeRule attributeID="eduPersonScopedAffiliation">
            <PermitValueRule xsi:type="ANY"/>
        </AttributeRule>
    </AttributeFilterPolicy>

Jeśli IdP obsługuje Office365, należy również dodać reguły:

  <AttributeFilterPolicy id="PolicyForWindowsAzureAD">
        <PolicyRequirementRule xsi:type="Requester" value="" />
        <AttributeRule attributeID="UserId">
                <PermitValueRule xsi:type="ANY"/>
        </AttributeRule>
        <AttributeRule attributeID="ImmutableID">
          <PermitValueRule xsi:type="ANY"/>
        </AttributeRule>
        <AttributeRule attributeID="transientId">
          <DenyValueRule xsi:type="ANY"/>
        </AttributeRule>
    </AttributeFilterPolicy>

Na potrzeby sprawdzenia działania IdP z testowym dostawcą usługi PIONIER.Id dodajemy:

 
<AttributeFilterPolicy id="PolicyForMyTestSP">
        <PolicyRequirementRule xsi:type="Requester" value="" />
        <AttributeRule attributeID="UserId">
                <PermitValueRule xsi:type="ANY"/>
        </AttributeRule>
        <AttributeRule attributeID="ImmutableId">
          <PermitValueRule xsi:type="ANY"/>
        </AttributeRule>
        <AttributeRule attributeID="email">
          <PermitValueRule xsi:type="ANY"/>
        </AttributeRule>
        <AttributeRule attributeID="uid">
          <PermitValueRule xsi:type="ANY" />
        </AttributeRule>
        <AttributeRule attributeID="transientId">
          <DenyValueRule xsi:type="ANY"/>
        </AttributeRule>
    </AttributeFilterPolicy>

W federacji PIONIER.Id będę rejestrowani dostawcy usług spoza eduGAIN i nie wspierający Geant Code of Conduct czy Research & Scholarship. W takich przypadkach po stronie IdP może być potrzebne dodanie filtra specyficznego dla danego dostawcy.

W części Dodawanie filtrów nowych usługodawców Shibboleth IdP są prezentowane filtry dla usługodawców PIONIER.Id.

Pobierz wzorcowy plik attribute-filter.xml

global.xml

Jest to plik, w którym umieszczane są potrzebne definicje komponentów Javy zw. beans, np. w celu wskazania dedykowanych rozwiązań przechowywania danych.

Zgoda użytkownika na przekazanie atrybutów

Podstawowe ustawienia związane z wyrażaniem zgody są umieszczone w pliku idp.properties. Własności te mają nazwy zaczynające się od id.consent. Domyślnie informacje o wyrażonej zgodzie są przechowywane w pliku w podkatalogu logs instalacji Shibboleth. Zaleca się jednak takie skonfigurowanie IdP, by informacja o zgodzie była przechowywana tych w bazie danych. W tym celu w pliku idp.properties umieszczamy:

idp.consent.StorageService = shibboleth.JPAStorageService
idp.consent.userStorageKeyAttribute = eduPersonPrincipalName
idp.consent.maxStoredRecords = -1

Natomiast w pliku konfiguracyjnym global.xml umieszczamy:

<bean id="shibboleth.JPAStorageService"
   class="org.opensaml.storage.impl.JPAStorageService"
   p:cleanupInterval="%{idp.storage.cleanupInterval:PT10M}"
   c:factory-ref="shibboleth.JPAStorageService.EntityManagerFactory" />
<bean id="shibboleth.JPAStorageService.EntityManagerFactory"
   class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
   <property name="persistenceUnitName" value="" />
   <property name="packagesToScan" value="org.opensaml.storage.impl" />
   <property name="dataSource" ref="shibboleth.JPAStorageService.DataSource" />
   <property name="jpaVendorAdapter" ref="shibboleth.JPAStorageService.JPAVendorAdapter" />
   <property name="jpaDialect">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
   </property>
</bean>
<!-- MySQL configuration -->
<bean id="shibboleth.JPAStorageService.JPAVendorAdapter"
   class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
   <property name="database" value="MYSQL" />
</bean>
<bean id="shibboleth.JPAStorageService.DataSource"
   class="com.zaxxer.hikari.HikariDataSource" destroy-method="close" lazy-init="true"
   p:driverClassName="com.mysql.jdbc.Driver"
   p:jdbcUrl="jdbc:mysql://localhost:3306/shibboleth"
   p:username="shibboleth"
   p:password="hasło użytkownika shibboleth" />

Tworzymy tablicę w bazie danych wskazanej w definicji shibboleth.JPAStorageService.DataSource.

CREATE TABLE `StorageRecords` (
  `context` varchar(255) NOT NULL,
  `id` varchar(255) NOT NULL,
  `expires` bigint(20) DEFAULT NULL,
  `value` longtext NOT NULL,
  `version` bigint(20) NOT NULL,
  PRIMARY KEY (`context`,`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

W pliku /opt/shibboleth-idp/conf/intercept/consent-intercept-config.xml w bloku ... dodajemy:

<value>eduPersonTargetedID</value>

Dodatkowe ustalenia w pliku idp.properties decydują o dodatkowych możliwościach w zakresie wyrażania zgody, np.

  • idp.consent.allowDoNotRemember - ustala że po wydaniu zgody przy kolejnych logowaniach nie jest prezentowana prośba o wyrażenie zgody, o ile nie uległy zmianie informacje podlegające zgodzie, domyślnie true
  • idp.consent.allowGlobal - opcja powodująca, że jedną z możliwości na liście decyzji jest zgoda na przekazywanie atrybutów do wszystkich dostawców usług, domyślnie true czyli opcja jest włączona
  • idp.consent.allowPerAttribute - opcja dająca możliwość wyączenia zgody dla konkretnego atrybutu (przez skasowanie zaznaczenia przy tym atrybucie) - domyślnie false
Wyłączenie zgody dla określonych dostawców usług (SP)

Jeśli dla określonego dostawcy usługi nie ma być wyświetlany formularz wyrażenia zgody, to w pliku relaying-party.xml w bloku ... należy dodać:

<bean parent="RelyingPartyByName" c:relyingPartyIds="nazwa usługi SP (entityId)">
            <property name="profileConfigurations">
   <list>
    <bean parent="SAML2.SSO" />
   </list>
 </property>
</bean>

Definicja metody uwierzytelnienia

Domyślną metodą uwierzytelnienia jest baza LDAP oraz para nazwa użytkownika i hasło. Decyduje o tym ustawienie w pliku idp.properties:

idp.authn.flows = Password

Definicja źródła uwierzytelniania jest umieszczona w pliku konfiguracyjnym ldap.properties, w parametrach idp.authn.LDAP.ldapURL, idp.authn.LDAP.useStartTLS, idp.authn.LDAP.useSSL, idp.authn.LDAP.returnAttributes, idp.authn.LDAP.baseDN, idp.authn.LDAP.userFilter, idp.authn.LDAP.bindDN, idp.authn.LDAP.bindDNCredential.

Bardziej zaawansowane ustawienia są umieszczane w authn/ldap-authn-config.xml.

Jeżeli IdP jest zintegrowany z usługą CAS (Central Authentication Service), to w pliku idp.properties wpisujemy:

idp.authn.flows = RemoteUser

W pliku webapp/WEB-INF/web.xml dodajemy poniższe wpisy:

  serverName
  logon.example.pl


 CAS Authentication Filter
 org.jasig.cas.client.authentication.AuthenticationFilter
  
   casServerLoginUrl
   https://cas.example.pl/login
  

<!-- CAS Validation Filter -->

 CAS Validation Filter
 org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter           
 
   casServerUrlPrefix
   https://cas.example.pl/
 
 
   redirectAfterValidation
   true
 

<!-- CAS HttpServletRequest Wrapper Filter -->

 CAS HttpServletRequest Wrapper Filter
 org.jasig.cas.client.util.HttpServletRequestWrapperFilter

<!-- CAS Assertion Thread Local Filter -->

 CAS Assertion Thread Local Filter
 org.jasig.cas.client.util.AssertionThreadLocalFilter

<!-- CAS Filter for Shibb RemoteUser -->

 CAS Authentication Filter
 /Authn/RemoteUser


 CAS Validation Filter
 /Authn/RemoteUser


 CAS HttpServletRequest Wrapper Filter
 /Authn/RemoteUser


 CAS Assertion Thread Local Filter
 /Authn/RemoteUser

Integracja Shibboleth IdP z logowaniem CAS

Najlepszą metodą integracji Shibboleth IdP z logowaniem via CAS jest użycie pluginu shib-cas-auth3.

Plugin dostępny jest na stronie https://github.com/Unicon/shib-cas-authn3.

Pobieramy bieżącą wersję (np. via przycisk "Clone or Download" i dalej Download ZIP) i rozpakowujemy.

Zgodnie z instrukcją na stronie pluginu przekopiowujemy pliki z katalogu IDP_HOME w odpowiednie miejsce drzewa instalacji Shibboleth IdP (/opt/shibboleth-idp/). W pliku konfiguracyjnym conf/idp.properties dodajemy

idp.authn.flows = Shibcas
# wskazanie serwera CAS oraz strony logowania CAS
shibcas.casServerUrlPrefix = https://cassserver.example.edu/cas
shibcas.casServerLoginUrl = ${shibcas.casServerUrlPrefix}/login
# wskazanie serwera Shibboleth
shibcas.serverName = https://shibserver.example.edu

W pliku conf/authn/general-authn.xml dodajemy w ramach bloku util:list (np. tuż przed znacznikiem końca tego bloku):

<bean id="authn/Shibcas" parent="shibboleth.AuthenticationFlow"
                p:passiveAuthenticationSupported="true"
                p:forcedAuthenticationSupported="true"
                p:nonBrowserSupported="false" />

W katalogu z rozpakowanym pluginem wykonujemy polecenie

./gradlew

W katalogu build/libs/ powinien pojawić się plik shib-cas-authenticator-wersja.jar (obecna wersja to 3.2.3). Plik ten należy skopiować do /opt/shibboleth-idp/edit-webapp/WEB-LIB/lib, a następnie w katalogu instalacji Shibboleth IdP należy wykonać:

bin/build.sh

Utworzona nowa aplikacja idp.war będzie zintegrowana z logowaniem CAS.

Internacjonalizacja/lokalizacja Shibboleth IdP

Shibboleth IdP obsługuje natywnie wszystkie języki, dla których przygotowano odpowiedni zestaw komunikatów. Domyślnie w podkatalogu messages w katalogu instalacyjnym (/opt/shibboleth-idp) znajdują się pliki:

  • authn-messages.properties
  • consent-messages.properties
  • error-messages.properties

Aby w aplikacji pojawiały się polskie napisy, należy w tym samym katalogu stworzyć na wzór plików oryginalnych, pliki:

  • authn-messages_pl.properties
  • consent-messages_pl.properties
  • error-messages_pl.properties

i dodatkowo skopiować oryginalne pliki na pliki z przyrostkiem _en, czyli:

  • authn-messages_en.properties
  • consent-messages_en.properties
  • error-messages_en.properties

Polskie tłumaczenia komunikatów są dostępne tutaj:

Aby były poprawnie wyświetlane znaki UTF-8, w pliku system/conf/global-system.xml w bloku dotyczącym dodajemy

p:defaultEncoding="UTF-8"

Zmiany w plikach podkatalogu system nie są zalecane, gdyż aktualizacja wersji spowoduje nadpisanie pliku. Konieczność dodania własności w tym pliku została zgłoszona na liście mailowej shibboleth-users i w kolejnej wersji nie będzie to potrzebne.

Konfiguracja wylogowania

W poprzednich wersjach Shibboletha wylogowanie nie było obsługiwane. W wersji 3 planowana jest realizacja wylogowania w zakresie, na jaki pozwala specyfika środowiska pracy aplikacji sfederowanych.Aby były obsługiwane zlecenia LogoutRequest należy w pliku konfiguracyjnym idp.properties zmienić domyślne ustawienia kilku własności:

  • ustawić magazyn sesji użytkownika po stronie serwera (domyślnie jest to realizowane po stronie klienta), w tym celu umieszczamy
idp.session.StorageService = shibboleth.JPAStorageService
  • uaktywniamy własności związane z przechowywaniem sesji:
idp.session.trackSPSessions = true
idp.session.secondaryServiceIndex = true 

Przechowywanie sesji wymaga również konfiguracji magazynu danych. Jeżeli podczas przygotowania obsługi wyrażania zgody (patrz Zgoda użytkownika na przekazanie atrybutów) ustalono przechowywanie zgody w tablicy StorageRecords, to konfiguracja wylogowania jest już zakończona, w przeciwnym razie należy zdefiniować w pliku conf/global.xml magazyn shibboleth.JPAStorageService tak jak opisano tutaj.

Deweloperzy Shibboleth IdP obiecują, że w wersji 3.2 będzie zrealizowana obsługa wylogowania.

Reinstalacja Shibboleth IdP

Jeśli jest potrzebne przebudowa głównego pliku aplikacji idp.war, po dokonaniu zmian w dystrybucji (np. dodanie pliku bliblioteki jar, zmiana jakiegoś pliku wzorcowego (.vm), czy stylu (.css) wykonujemy w katalogu dystrybucji Shibboleth IdP:

./bin/build.sh

i zatwierdzamy katalog. Nowo utworzony plik idp.war należy umieścić w katalogu instalacji Shibboleth IdP, np. /opt/shibboleth-idp/war.

Aktualizacja wersji Shibboleth IdP

Aktualizację wersji Shibboleth 3.X realizujemy następująco:

  • pobieramy nową wersję i rozpakowujemy
  • w katalogu dystrybucji dodajemy wszystkie potrzebne pliki jar - zgodnie z opisem w punkcie
  • wykonujemy
./bin/install.sh
  • zatwierdzamy katalog dystrybucji, a jako katalog instalacji podajemy ten sam katalog, w którym jest zainstalowana poprzednia wersja Shibboleth /opt/shibboleth-idp/

Ponieważ katalog już istnieje nie będą wgrywane pliki konfiguracyjne, powstanie nowy plik idp.war.

Dodawanie filtrów nowych usługodawców Shibboleth IdP

Jeśli nowa usługa wymaga specyficznej konfiguracji zasad dostarczania atrybutów, należy dodać nowy filtr w pliku attribute-filter.xml.

Poniżej wykaz usług zarejestrowanych w PIONIER.Id wymagających specyficznej konfiguracji:

Usługa Webkonferencje https://webconf.pionier.net.pl

 

Atrybuty email, cn są wymagane, atrybuty eduPersonPrincipalName oraz eduPersonEntitlement są opcjonalne. Usługa ta wymaga również podania atrybutu eduPersonTargetedId - przekazywanie tego atrybutu realizuje globalna reguła releasePermanentIdToAnyone opisany w Konfiguracja / attribute-filter.xml

Atlases Pathology Images http://atlases.muni.cz