Login Login
MORE

WIDGETS

Widgets

Wanted articles
Who is online?
Article tools

Shibboleth IdP - wersja 4

Z MAN-HA wiki


Niezbędne komponenty dodatkowe

Instalacja Shibboleth IdP 4.X

Bieżącą stabilną wersją jest V4.2.1

Pobieramy pakiet Shibboleth IdP z repozytorium https://shibboleth.net/downloads/identity-provider/latest/, np. pobranie wersji 4.2.1:

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

Pobieramy wymienione w poprzedniej sekcji pakiety mysql, commons*, HikariCP.

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 messages/ dystrybucji umieszczamy pliki z wersją polską komunikatów. Tłumaczenia są do pobrania wg linku na stronie https://wiki.shibboleth.net/confluence/display/IDP4/MessagesTranslation.

Uruchamiamy instalację pakietu:

./bin/install.sh 

Wskazujemy parametry instalacyjne:

Source (Distribution) Directory: [/opt/shibboleth-identity-provider-4.2.1] 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 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.

Jeżeli pojawi się potrzeba dodania do  pliku aplikacji dodatkowych biblioteki, dodanych w katalogu '/opt/shibboleth-idp/edit-webapp/'WEB-INF/lib/, czy zmieniane są pliki zawierające tłumaczenia, należy ponowić utworzenie aplikacji.

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

Instalacja Jetty

Rekomendowanym serwerem webowym, na którym będzie uruchamiana aplikacja Shibboleth IdP, jest Jetty.

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 (https://tcs.pionier.gov.pl). Certyfikat serwera musi zostać przekształcony do odpowiedniej postaci, wymaganej przez oprogramowanie serwera web.

Dokładne informacje na temat przygotowania serwera obsługującego aplikację znajdują się na stronie Instalacja Jetty.

Konfiguracja Shibboleth IdP 4.X

Pliki konfiguracyjne Shibboleth 4 IdP są umieszczone w katalogu /opt/shibboleth-idp/conf. W katalogu /opt/shibboleth-idp/credentials znajdują się 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/IDP4/Configuration#Configuration-InstallationLayout została opisana rola poszczególnych podkatalogów w drzewie instalacji Shibboleth.

Najistotniejsze ustawienia są umieszczone w plikach typu properties. Drugą formą konfiguracji są pliki w formacie XML.

Poniżej omówione są pliki konfiguracyjne, które mogą wymagać dostosowania.

idp.properties

W tym pliku podczas instalacji są wpisywane ścieżki do certyfikatów, hasła do plików z kluczami, nazwa IdP itp. Przed instalacją IdP nie są potrzebne żadne zmiany w tym pliku. W trakcie procesu instalacji zapisywane są wybrane ustawienia, jak np. nazwa serwera. 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 zarządzanie ustawieniami w ramach profili.

Modyfikacje pliku mogą być potrzebne w przypadku, gdy np. w odniesieniu do konkretnych dostawców usług rezygnujemy z pytania o zgodę na przekazywanie atrybutów.

metadata-providers.xml

Plik ten zawiera konfigurację metadanych, z których korzysta IdP.

W pliku, w postaci komentarzy, są podane przykłady użycia podstawowych metod definicji metadanych.

Domyślnie w pliku nie są umieszczone żadne wskazania metadanych.

Szczegółowy opis możliwości w zakresie konfiguracji źródeł metadanych znajduje się na stronie

https://wiki.shibboleth.net/confluence/display/IDP4/MetadataConfiguration

W pliku tym należy dodać blok (np. przed elementem zamykającym )

 
<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

W ten sposób zapewniamy pobieranie przez serwer IdP metadanych PIONIER.Id/eduGAIN, które są niezbędne do realizacji komunikacji z usługami (Service Providers). Wśród usług zdefiniowanych w powyższym bloku jest również usługa testowa PIONIER.Id, dostępna pod adresem https://aai.pionier.net.pl/test/attributes.php

Zapewnienie współpracy serwera IdP z tą usługą jest wymagane na etapie sprawdzenia, czy serwer IdP jest gotowy do rejestracji.

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. Plik wymaga dostosowania, by IdP tworzył identyfikator typu persistent i zapisywał go do bazy danych, w tym celu należy zapewnić istnienie następujących wpisów:

idp.persistentId.sourceAttribute = eduPersonPrincipalName
idp.persistentId.encoding = BASE32
idp.persistentId.generator = shibboleth.StoredPersistentIdGenerator
idp.persistentId.dataSource = nazwa_zrodla_danych
idp.persistentId.salt = wartość_losowa_używana_do_wyliczenia_persistentId

Parametr idp.persistentId.sourceAttribute określa atrybut używany do wyliczania wartości persistentId. Zalecany jest wybór atrybutu gwarantującego unikatowość i niepowtarzalność. Jeśli eduPersonPrincipalName nie spełnia tych warunków należy wybrać inny atrybut.

Parametr idp.persistentId.generator ustala, że identyfikator persistenId ma być generowany za pomocą klasy umożliwiającej zapamiętanie tego identyfikatora (shibboleth.StoredPersistentIdGenerator). Dzięki temu identyfikatory będą dostępne w bazie danych i będzie możliwa lepsza obsługa ich trwałości.

Parametr idp.persistentId.dataSource wskazuje nazwę magazynu do przechowywania identyfikatorów. Sam magazyn jest definiowany w pliku konfiguracyjnym global.xml lub saml-nameid.xml, tutaj podajemy jedynie zdefiniowaną tam unikatową nazwę.

saml-nameid.xml

W pliku są m.in. definiowane mechanizmy generowania identyfikatora persistentId. 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>

global.xml

Jest to plik, w którym umieszczane są potrzebne definicje komponentów Javy zw. beans, np. przeznaczone do przechowywania danych.Dodajemy tu definicję źródła podanego w ustawieniu w pliku saml-nameid.properties, we własności idp.persistentId.dataSource:

idp.persistentId.dataSource = nazwa_zrodla_danych

Umieszczamy ją np. przed ostatnim wierszem zawierającym .

<bean id="nazwa_zrodla_danych" class="org.apache.commons.dbcp2.BasicDataSource"
    p:driverClassName="com.mysql.cj.jdbc.Driver"
    p:url="jdbc:mysql://localhost:3306/shibboleth"
    p:username="użytkownik"
    p:password="hasło użytkownika"
    p:maxIdle="5"
    p:maxWaitMillis="15000"
    p:testOnBorrow="true"
    p:validationQuery="select 1"
    p:validationQueryTimeout="5" />
</beans>

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

CREATE TABLE shibpid (
  `localEntity` varchar(255) NOT NULL,
  `peerEntity` varchar(255) NOT NULL,
  `persistentId` varchar(50) NOT NULL,
  `principalName` varchar(50) NOT NULL,
  `localId` varchar(50) NOT NULL,
  `peerProvidedId` varchar(50) DEFAULT NULL,
  `creationDate` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
  `deactivationDate` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`localEntity`,`peerEntity`,`persistentId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Również w pliku global.xml jest deklarowane miejsce przechowywania dodatkowych danych IdP, np. danych sesyjnych, m.in na potrzeby obsługi wylogowania. Definicja obszaru bazy danych na dane IdP wygląda następująco:

<!-- DB-independent Configuration -->
 
<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="packagesToScan" value=""/>
      <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>
 
<!-- DB-dependent Configuration -->
 
<bean id="shibboleth.JPAStorageService.JPAVendorAdapter" 
      class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
      <property name="database" value="MYSQL" />
</bean>
 
<!-- Bean to store IdP data unrelated with persistent identifiers on 'shibboleth' database -->
<bean id="shibboleth.JPAStorageService.DataSource"
      class="com.zaxxer.hikari.HikariDataSource" destroy-method="close" lazy-init="true"
      p:driverClassName="com.mysql.cj.jdbc.Driver"
      p:jdbcUrl="jdbc:mysql://localhost:3306/shibboleth"
      p:username="użytkownik"
      p:password="hasło użytkownika" />

attribute-resolver.xml

W tym pliku jest ustalany sposób tworzenia atrybutów oraz ich kodowania przed wysłaniem.Plik ten zmienił się w porównaniu do v.3.Atrybuty są definiowane w blokach AttributeDefinition, np.

   
<AttributeDefinition id="eduPersonPrincipalName" xsi:type="Scoped" scope="%{idp.scope}">
   <InputAttributeDefinition ref="uid" />
</AttributeDefinition>
<AttributeDefinition xsi:type="Simple" id="mail">
   <InputDataConnector ref="myLDAP" attributeNames="mail"/>
</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 mail - jest pobierany z bazy wskazanej w elemencie ref (tu myLDAP).

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 xsi:type="SAML2NameID" 
                     nameIdFormat="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
                     id="eduPersonTargetedID">
    <InputDataConnector ref="StoredId" attributeNames="persistentID" />
</AttributeDefinition>

Źródłem tego atrybutu jest baza wskazana jako StoredId

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 id="StoredId" xsi:type="StoredId"
        generatedAttributeID="persistentID"
        salt="%{idp.persistentId.salt}"
        queryTimeout="0">
   <InputDataConnector ref="myLDAP" attributeNames="%{idp.persistentId.sourceAttribute}" />
   <BeanManagedConnection>%{idp.persistentId.dataSource}</BeanManagedConnection>
</DataConnector>

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

Aby aplikacja Shibboleth IdP obsługiwała atrybuty SCHAC, należy pamiętać o umieszczeniu definicji tych atrybutów, np.

    <AttributeDefinition xsi:type="Simple" id="schacHomeOrganization">
           <InputDataConnector ref="myLDAP" attributeNames="schacHomeOrganization"/>
    </AttributeDefinition>
    <AttributeDefinition xsi:type="Simple" id="schacHomeOrganizationType">
           <InputDataConnector ref="myLDAP" attributeNames="schacHomeOrganizationType"/>
    </AttributeDefinition>
    <AttributeDefinition xsi:type="Simple" id="schacPersonalUniqueCode">
           <InputDataConnector ref="myLDAP" attributeNames="schacPersonalUniqueCode"/>
    </AttributeDefinition>

Jeśli chcemy, by dostawca tożsamości przekazywał statyczną wartość określonego atrybutu, np. atrybutu schacHomeOrganization, w którym oczekiwana jest nazwa domenowa instytucji, czy atrybutu schacHomeOrganizationType, w którym oczekiwany jest typ instytucji, warto skorzystać z funkcjonalności [StaticDataConnector]. Definiujemy odpowiednie atrybuty wskazując staticAttributes jako źródło danych:

    <AttributeDefinition xsi:type="Simple" id="schacHomeOrganizationType">
           <InputDataConnector ref="staticAttributes" attributeNames="schacHomeOrganizationType"/>
    </AttributeDefinition>
    <AttributeDefinition xsi:type="Simple" id="schacPersonalUniqueCode">
           <InputDataConnector ref="myLDAP" attributeNames="schacPersonalUniqueCode"/>
    </AttributeDefinition>

a na końcu pliku attribute-resolver.xml dodajemy:

<DataConnector  id="staticAttributes"  xsi:type="Static" >
    <Attribute id="schacHomeOrganization">
        <Value>domena.instytucji.pl</Value>
     </Attribute>
     <Attribute id = "schacHomeOrganizationType" >
        <Value>urn:schac:homeOrganizationType:pl:university</Value>
     </Attribute>
    </DataConnector>

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.

Zasady ogólne

Serwer 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.

Kategorie usług

Dostawcy tożsamości zarejestrowani w PIONIER.Id mogą zadeklarować w metadanych, że akceptują określone zasady dotyczące publikacji atrybutów.

Kategoria CoCo

Zasady GÉANT Data Protection Code of Conduct są opisane na stronie https://wiki.refeds.org/display/CODE/Data+Protection+Code+of+Conduct+HomeInstrukcje https://wiki.geant.org/display/eduGAIN/CoCo+Recipe+for+a+Home+Organisation opisują wymagania po stronie IdP.Serwer IdP wspierający kategorię CoCo realizuje odpowiednią publikację atrybutów w przypadku komunikacji z usługami zgodnymi z CoCo. Gwarantuje to poniższy blok (attributeValue="http://www.geant.net/uri/dataprotection-code-of-conduct/v1" oznacza deklarację dotyczącą Code of Conduct): oraz stosowanie zasad 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="AttributeInMetadata" onlyIfRequired="true"/>
        </AttributeRule>
        <AttributeRule attributeID="cn">
            <PermitValueRule xsi:type="AttributeInMetadata" onlyIfRequired="true"/>
        </AttributeRule>
        <AttributeRule attributeID="sn">
            <PermitValueRule xsi:type="AttributeInMetadata" onlyIfRequired="true"/>
        </AttributeRule>
        <AttributeRule attributeID="givenName">
            <PermitValueRule xsi:type="AttributeInMetadata" onlyIfRequired="true"/>
        </AttributeRule>
        <AttributeRule attributeID="mail">
            <PermitValueRule xsi:type="AttributeInMetadata" onlyIfRequired="true"/>
        </AttributeRule>
        <AttributeRule attributeID="eduPersonPrincipalName">
            <PermitValueRule xsi:type="AttributeInMetadata" onlyIfRequired="true"/>
        </AttributeRule>
        <AttributeRule attributeID="eduPersonScopedAffiliation">
            <PermitValueRule xsi:type="AttributeInMetadata" onlyIfRequired="true"/>
        </AttributeRule>
        <AttributeRule attributeID="eduPersonAffiliation">
            <PermitValueRule xsi:type="AttributeInMetadata" onlyIfRequired="true"/>
        </AttributeRule>
        <AttributeRule attributeID="schacPersonalUniqueCode">
          <PermitValueRule xsi:type="AND">
            <Rule xsi:type="AttributeInMetadata" onlyIfRequired="true"/>
            <Rule xsi:type="ValueRegex" regex="^urn:schac:personalUniqueCode:int:esi:.*$" />
         </PermitValueRule>
        </AttributeRule>
        <AttributeRule attributeID="schacHomeOrganization">
          <PermitValueRule xsi:type="AttributeInMetadata" onlyIfRequired="false"/>
        </AttributeRule>
        <AttributeRule attributeID="schacHomeOrganizationType">
          <PermitValueRule xsi:type="AttributeInMetadata" onlyIfRequired="false"/>
        </AttributeRule>
    </AttributeFilterPolicy>
Kategoria REFEDS Research and Scholarship

Kategoria REFEDS R&S jest zarezerwowana dla usług działających w obszarze nauki i badań.Na stronie https://refeds.org/category/research-and-scholarship opisano zasady publikacji atrybutów. Serwer IdP wspierający kategorię REFEDS R&S realizuje odpowiednią publikację atrybutów, jeśli usługa deklaruje zgodność z R&S. Gwarantuje to poniższy blok (attributeValue="http://refeds.org/category/research-and-scholarship" oznacza deklarację dotyczącą REFEDS R&S. Odpowiadają za to poniższe reguły:

    <AttributeFilterPolicy id="releaseToRandS">
        <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="eduPersonTargetedID">
            <PermitValueRule xsi:type="ANY"/>
        </AttributeRule>
        <AttributeRule attributeID="eduPersonScopedAffiliation">
            <PermitValueRule xsi:type="ANY"/>
        </AttributeRule>
    </AttributeFilterPolicy>
Kategoria ESI

Dostawcy tożsamości zarejestrowani w PIONIER.Id mogą deklarować akceptowanie ESI Entity Category https://wiki.geant.org/display/SM/ESI+Entity+Category+-+Consultation. Za realizację zasad tej kategorii odpowiadają poniższe reguły:

    <AttributeFilterPolicy id="MyAcacemicID-ESI">
      <PolicyRequirementRule xsi:type="EntityAttributeExactMatch"
         attributeName="http://macedir.org/entity-category"
         attributeValue="https://myacademicid.org/entity-categories/esi"/>
      <AttributeRule attributeID="schacPersonalUniqueCode">
        <PermitValueRule xsi:type="ValueRegex" regex="^urn:schac:personalUniqueCode:int:esi:.*$" />
      </AttributeRule>
    </AttributeFilterPolicy>

Przykłady obsługi innych usług

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="email">
          <PermitValueRule xsi:type="ANY"/>
        </AttributeRule>
        <AttributeRule attributeID="eduPersonPrincipalName">
          <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.

Rejestr atrybutów: conf/attributes/default-rules.xml, conf/attributes/custom/

W pliku /opt/shibboleth-idp/conf/attributes/default-rules.xml zdefiniowane są zasady transkodowania atrybutów. Domyślne reguły definiowane są w plikach:

inetOrgPerson.xml
eduPerson.xml
eduCourse.xml
samlSubject.xml
Dodanie niestandardowych reguł - obsługa eduPersonTargetedID

W katalogu /opt /shibboleth-idp/conf/attributes/custom można umieścić własne reguły, dotyczące danej instalacji. W celu zapewnienia transkodowania atrybutu eduPersonTargetedID należy w tym katalogu umieścić plik eduPersonTargetedID.properties o zawartości (pobierz plik eduPersonTargetedID.properties)

<?xml version="1.0" encoding="UTF-8"?>
id=eduPersonTargetedID
transcoder=SAML2XMLObjectTranscoder
saml2.name=urn:oid:1.3.6.1.4.1.5923.1.1.1.10
displayName.en=Opaque per-service identifier
displayName.pl=Anonimowy identyfikator us\u0142ugi
description.en=Opaque per-service identifier
description.pl=Anonimowy identyfikator us\u0142ugi
saml1.encodeType=false

Po restarcie aplikacji jetty zostanie wczytana nowa konfiguracja.

Dodanie obsługi atrybutów SCHema for ACademia (SCHAC)

Korzystanie ze schematu SCHAC jest niezbędne jeśli dostawca tożsamości chce korzystać z europejskich usług związanych z mobilnością studentów: https://wiki.geant.org/display/SM/MyAcademicID+Project

Wymagania dotyczące niezbędnych atrybutów są opisane na stronie: https://wiki.aai.pionier.net.pl/index.php?title=Federacja:ESI. Należy pobrać plik zawierający definicję transkodowania atrybutów SCHAC schac.xml i umieścić w katalogu /opt/shibboleth-idp/conf/attributes/.W pliku /opt/shibboleth-idp/conf/attributes/default-rules.xml należy dodać wiersz (najlepiej jako kolejny wiersz za ostatnią linią import:

<import resource="schac.xml" />

Po restarcie aplikacji jetty zostanie wczytana nowa konfiguracja.

Zgoda użytkownika na przekazanie atrybutów

Jeżeli instalacja wersji 4.1.0 jest nowa, tzn. nie jest aktualizacją z niższej wersji, w której była aktywa zgoda na przekazywanie atrybutów niezbędne jest włączenie modułu idp.intercept.Consent.Polecenie

/opt/shibboleth-idp/bin/module.sh

pokazuje listę modułów oraz ich stanów (ENABLED/DISABLED)Polecenie

/opt/shibboleth-idp/bin/module.sh -e idp.intercept.Consent

ustala stan ENABLED dla modułu idp.intercept.Consent

W pliku /opt/shibboleth-idp/conf/intercept/consent-intercept-config.xml są definiowane dodatkowe ustawienia związane z modułem zgody. W tym pliku m.in. można zgodnie z obowiązującą na uczelni polityką, umieszczać atrybuty, które są umieszczane na tzw. whitelist lub blacklist podczas działania modułu wyrażania zgody.

Pliki /opt/shibboleth-idp/views/intercept/attribute-release.vm i /opt/shibboleth-idp/views/intercept/terms-of-use.vm są plikami wzorcowymi dla stron związanych z udzielaniem zgody na przekazanie atrybutów.

Aby zgoda była aktywna w odniesieniu do dowolnego dostawcy usługi, pliku konfiguracyjnym '/opt/shibboleth-idp/conf/relying-party-xml, w bloku bean o id="shibboleth.DefaultRelyingParty" modyfikujemy wiersz dotyczący SAML2.SSO:

<bean parent="SAML2.SSO" p:postAuthenticationFlows="attribute-release" />

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 w bazie danych. W tym celu w pliku idp.properties umieszczamy:

idp.consent.StorageService = shibboleth.JPAStorageService
idp.consent.attribute-release.userStorageKey = shibboleth.consent.PrincipalConsentStorageKey
idp.consent.userStorageKeyAttribute = eduPersonPrincipalName
idp.consent.maxStoredRecords = -1

Moduł zgody korzysta z ustawień dot. shibboleth.JPAStorage w pliku konfiguracyjnym global.xml.

Z kolei w bazie danych tworzymy tablicę StorageRecords do przechowywania m.in. zgód.

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,
  `creationDate` timestamp NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
  PRIMARY KEY (`context`,`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


Ustawienia 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. Polecenie:

/opt/shibboleth-idp/bin/module.shpokazuje w wynikach:
Module: idp.authn.Password [ENABLED]

Definicja źródła uwierzytelniania jest umieszczona w pliku konfiguracyjnym ldap.properties, w parametrachidp.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. Włączenie innego trybu, np. gdy dostawca tożsamości korzysta z CAS-a wymaga aktywizacji odpowiedniego modułu, np.:

/opt/shibboleth-idp/bin/module.sh -t idp.authn.RemoteUser

Integracja Shibboleth IdP z logowaniem CAS

Za pomocą pluginu shib-cas-auth

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

Na stronie https://github.com/Unicon/shib-cas-authn jest dostępna bieżąca wersja pluginu wraz z opisem instalacji.

Pod adresem https://github.com/Unicon/shib-cas-authn/releases umieszczono wszystkie potrzebne pliki wersji 4.0.0.

Alternatywnie można pobrać ze strony https://github.com/Unicon/shib-cas-authn bieżącą wersję (np. via przycisk "Clone or Download" i dalej Download ZIP lub używając polecenia git), następnie rozpakować i przygotować samodzielnie pliki jar.

W katalogu z rozpakowanym pluginem wykonujemy polecenie

./gradlew clean build

Do katalogu /opt/shibboleth-idp/edit-webapp/WEB-LIB/lib kopiujemy dwa pliki jar:

  • shib-cas-authenticator-4.0.0.jar
  • cas-client-core-3.6.0.jar (znajduje się w podkatalogu build/dist-tmp/edit-webapp/WEB-INF/lib/ rozpakowanego plugina)

Do katalogu /opt/shibboleth-idp/edit-webapp/ kopiujemy IDP_HOME/edit-webapp/no-conversation-state.jsp z katalogu rozpakowanego plugina.

Do katalogu /opt/shibboleth-idp/edit-webapp/WEB-INF kopiujemy plik /opt/shibboleth-idp/dist/webapp/WEB-INF/web.xml.

Włączamy moduł idp.authn.external:

/opt/shibboleth-idp/bin/module.sh -e idp.authn.External

co powoduje utworzenie pliku /opt/shibboleth-idp/conf/authn/external-authn-config.xml.

W tym pliku za wierszami:

<!--
    The idp.authn.External.externalAuthnPath property controls the default location to use.
    For advanced cases, define a bean called "shibboleth.authn.External.externalAuthnPathStrategy"
    of type Function<ProfileRequestContext,String> that returns the path to use.
-->

umieszczamy blok:

<bean id="shibboleth.authn.External.externalAuthnPath" class="java.lang.String"
        c:_0="contextRelative:Authn/External" />


W pliku konfiguracyjnym conf/idp.properties dodajemy/modyfikujemy ustawienia:

idp.authn.flows = External
# 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 katalogu instalacji Shibboleth IdP /opt/shibboleth-idp wykonujemy:

bin/build.sh

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

Przy użyciu funkcjonalności SAML proxy do innego dostawcy tożsamości

Jeśli serwer CAS wspiera protokół SAML i jest przygotowany do działania jako dostawca tożsamości SAML2, można skorzystać z funkcjonalności umożliwiającej przekazanie zleceń SAML-owych do kolejnego dostawcy. W tej sytuacji Shibboleth IdP proxujący zlecenie występuje w roli usługodawcy (SP), natomiast serwer CAS staje się dostawcą tożsamości.Na stronach:

opisano szczegółowo konfigurację Shibboleth IdP.Niezbędnym elementem jest zapewnienie, by oba IdP (Shibboleth i CAS) używały wspólnego atrybutu powiązanego z użytkownikiem. Chodzi o to by serwer CAS pełniący rolę dostawcy tożsamości w ramach pozytywnej odpowiedzi na uwierzytelnienie przekazał do Shibboleth IdP atrybut identyfikujący użytkownika, za pomocą którego Shibboleth IdP realizuje etap powiązania dodatkowych atrybutów z użytkownikiem (attribute resolution). W celu zapewnienia funkcjonalności SAML proxy należy:

  • W metadanych po stronie Shibboleth IdP umieścić metadane serwera CAS (w roli IdP, czyli zawierające IDPSSODescriptor.
  • W metadanych po stronie CAS umieścić metadane Shibboleth IdP (w roli SP, czyli zawierające SPSSODescriptor). Domyślne metadane nie zawierają definicji tej roli, trzeba samodzielnie dodać blok o postaci:
 <!-- New SP block -->
    <SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
 
        <KeyDescriptor use="signing">
            <ds:KeyInfo>
                <ds:X509Data>
                    <ds:X509Certificate>
                    ...Signing Certificate from IdP...
                    </ds:X509Certificate>
                </ds:X509Data>
            </ds:KeyInfo>
        </KeyDescriptor>
        <KeyDescriptor use="encryption">
            <ds:KeyInfo>
                <ds:X509Data>
                    <ds:X509Certificate>
                    ...Encryption Certificate from IdP...
                    </ds:X509Certificate>
                </ds:X509Data>
            </ds:KeyInfo>
        </KeyDescriptor>
 
    <AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://idp.example.ac.uk/idp/profile/Authn/SAML2/POST/SSO" index="0"/>
</SPSSODescriptor>

W konfiguracji Shibboleth IdP trzeba wykonać następujące zmiany:

  • Aktywować uwierzytelnienie SAML - w tym celu w pliku /opt/shibboleth-idp/conf/authn/saml-authn-config.xml należy odkomentować bean shibboleth.authn.SAML.discoveryFunction i zedytować wartość target:
<bean id="shibboleth.authn.SAML.discoveryFunction" parent="shibboleth.Functions.Constant"
            c:target="https://adres_serwera_CAS/idp" />
  • W pliku /opt/shibboleth-idp/conf/idp.properties ustawić wartość SAML przy rodzaju uwierzytelnienia
idp.authn.flows=SAML
  • Zaktualizować plik /opt/shibboleth-idp/conf/attribute-filter.xml, by zawierał definicję wspólnego atrybutu, np. zakładając, że CAS przekazuje do Shibboleth IdP atrybut uid:
<AttributeFilterPolicy id="proxy">
    <PolicyRequirementRule xsi:type="Issuer" value="" />
    <AttributeRule attributeID="uid" permitAny="true" />
</AttributeFilterPolicy>
  • Zaktualizować plik /opt/shibboleth-idp/conf/attribute-resolver.xml, by umożliwić obsługę atrybutu odebranego z CAS:
<AttributeDefinition id="proxied-uid" xsi:type="SubjectDerivedAttribute"
        forCanonicalization="true"
        principalAttributeName="uid" />
  • Zaktualizować plik /opt/shibboleth-idp/conf/c14n/attribute-sourced-subject-c14n-config.xml, by aktywne były bloki:
<util:list id="shibboleth.c14n.attribute.AttributesToResolve">
 <value>proxied-uid</value>
</util:list>
<util:list id="shibboleth.c14n.attribute.AttributeSourceIds">
 <value>proxied-uid</value>
</util:list>

Po restarcie Shibboleth IdP powinno działać logowanie via CAS w funkcji proxy SAML.

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/) pojawia się plik messages.properties.

Aby w aplikacji pojawiały się polskie napisy, należy w tym samym katalogu umieścić plik messages_pl.properties.

Plik pobieramy wg wskazówek na stronie https://wiki.shibboleth.net/confluence/display/IDP4/MessagesTranslation z serwisu Zenata.

Konfiguracja wylogowania

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
  • uaktywnić 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.

Dostosowanie metadanych dostawcy tożsamości

W czasie instalacji dostawcy tożsamości w pliku /opt/shibboleth-idp/metadata/idp-metadata.xml są umieszczane metadane IdP. Plik ten wymaga dostosowania przed przekazaniem go do administratorów federacji PIONIER.Id.Poniżej zamieszczamy opis zmian:

  • usunąć wszelkie komentarze typu This is example metadata only itp.
  • usunąć z elementu EntityDescriptor atrybut validuntil
  • odkomentować blok mdui:UIInfo i umieścić w nim elementy dot. danego IdP, wg opisu na stronie https://wiki.aai.pionier.net.pl/index.php/Federacja:Metadane w sekcji Informacji dodatkowe - rozszerzenie MDUI
  • wyrzucić zakomentowane wiersze
<!--
<ArtifactResolutionService Binding="urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding" Location="https://......:8443/idp/profile/SAML1/SOAP/ArtifactResolution" index="1"/>
-->
 
<!--
<SingleSignOnService Binding="urn:mace:shibboleth:1.0:profiles:AuthnRequest" Location="https://....../idp/profile/Shibboleth/SSO"/>
-->
  • odkomentować blok zawierający trzy elementy SingleLogoutService
  • odkomentować cały blok zawierający element AttributeAuthorityDescriptor, usunąć w nim wiersz
<!--
<ArtifactResolutionService Binding="urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding" Location="https://......:8443/idp/profile/SAML1/SOAP/ArtifactResolution" index="1"/>
-->

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. Upewniamy się, że nowy plik idp.war został umieśczony w katalogu instalacji Shibboleth IdP, np./opt/shibboleth-idp/war.

Restartujemy usługę.

Aktualizacja wersji Shibboleth IdP

Aktualizację wersji Shibboleth 4.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:


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

 
<AttributeFilterPolicy id="ATLASES">	
      <PolicyRequirementRule xsi:type="Requester" value="" />	
      <AttributeRule attributeID="mail">	
          <PermitValueRule xsi:type="ANY"/>
      </AttributeRule>		
      <AttributeRule attributeID="eduPersonPrincipalName">		
          <PermitValueRule xsi:type="ANY"/>	
      </AttributeRule>	
    </AttributeFilterPolicy>

Zastosowanie bazy relacyjnej do realizacji uwierzytelnienia

Domyślna konfiguracja Shibboleth-IdP jest przystosowania do użycia bazy LDAP jako źródła danych użytkowników.Jeśli konta użytkowników sa umieszczone w bazie relacyjnej, należy przełączyć się na korzystanie z handlera JAAS (Java Authentication and Authorization Service).

W tym celu, w pliku /opt/shibboleth-idp/conf/authn/password-authn-config.xml należy zakomentować wiersz dot. LDAPValidator i uaktywnić użycie JAASValidator:

<util:list id="shibboleth.authn.Password.Validators">
        <!-- <ref bean="shibboleth.LDAPValidator" /> -->
        <!-- <ref bean="shibboleth.KerberosValidator" /> -->
        <ref bean="shibboleth.JAASValidator" />
        <!-- <bean parent="shibboleth.HTPasswdValidator" p:resource="%{idp.home}/credentials/demo.htpasswd" /> -->
</util:list>

Poza tym należy utworzyć plik /opt/shibboleth-idp/conf/authn/jaas.config', w którym definiowany jest dostęp do relacyjnej bazy danych:

ShibUserPassAuth {
   relationalLogin.DBLogin required debug=true
   dbDriver="com.mysql.cj.jdbc.Driver"
   userTable="tabela_w_bazie_użytkowników"
   userColumn="kolumna_z_nazwą_użytkownika"
   passColumn="kolumna_z_hasłem_użytkownika"
   dbURL="jdbc:mysql://localhost:3306/baza_użytkowników"
   dbUser="użytkownik_uprawniony_do_korzystania_z_bazy"
   dbPassword="hasło_uprawnionego_użytkownika"
   hashAlgorithm="SHA-256"
   saltColumn=""
   errorMessage="Invalid password";
};

w wierszu hashAlghorithm należy wpisać algorytm używany do szyfrowania haseł użytkowników.

Do katalogu /opt/shibboleth-idp/edit-webapp/WEB-INF/lib należy wgrać ten plik. Jest to biblioteka realizująca dostęp do bazy relacyjnej zgodny z JAAS (https://github.com/robertogallea/jaas_relational_login).

Następnie przygotowujemy aktualną wersję Shibboleth IdP:

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

i restartujemy serwis jetty. Tabela wskazana jako userTable musi zawierać kolumny wymienione w jaas.config jako userColumn i passColumn.

Powyższa instrukcja dotyczy wyłącznie realizacji uwierzytelnienia via relacyjna baza danych. Jeśli atrybuty użytkowników również są umieszczone w relacyjnej bazie danych należy odpowiednio dostosować konfigurację w pliku /opt/shibboleth-idp/conf/attribute-resolver.xml. Należy zdefiniować bazę relacyjną jako źródło atrybutów użytkownika, np.

    <DataConnector
            id="mySQL"
            xsi:type="RelationalDatabase">
            <SimpleManagedConnection
            jdbcDriver="com.mysql.cj.jdbc.Driver"
            jdbcURL="jdbc:mysql://localhost:3306/baza_użytkowników"
            jdbcUserName="użytkownik_uprawniony_do_kontaktu_z_bazą"
            jdbcPassword="jego_hasło" />
       <QueryTemplate>
       <![CDATA[
         SELECT * FROM tabela_zawierająca_użytkowników WHERE username='$resolutionContext.principal'
       ]]>
       </QueryTemplate>
    </DataConnector>


Poza tym w definicji atrybutów należy wszędzie wskazywać id użyte w bloku definiującym dostęp do bazy (tu 'mySQL).

Jeśli np. baza danych zawiera tabelę użytkowników o poniższym schemacie:

CREATE TABLE `users` (
  `username` varchar(64) NOT NULL,
  `password` varchar(100) NOT NULL,
  `uid` varchar(64) DEFAULT NULL,
  `schacPersonalUniqueCode` varchar(64) DEFAULT NULL,
  `mail` varchar(64) DEFAULT NULL,
  `eduPersonAffiliation` varchar(64) DEFAULT NULL,
  `givenName` varchar(64) DEFAULT NULL,
  `sn` varchar(64) DEFAULT NULL,
  `cn` varchar(64) DEFAULT NULL,
  PRIMARY KEY (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

to po udanym uwierzytelnieniu zostaną pobranie atrybuty danego użytkownika.