Skip to content
Snippets Groups Projects
Commit 6eb3a8a4 authored by Benjamin Ledel's avatar Benjamin Ledel
Browse files

* shhiboleth documentation + improvements

parent 06d692df
Branches
No related tags found
No related merge requests found
# Shibboleth
Shibboleth is a single sign-on login system for computer networks and the Internet. It allows people to sign in using just one identity to various systems run by federations of different organizations or institutions. The federations are often universities or public service organizations.
## General information
Shibboleth is a web-based technology that implements the HTTP/POST artifact and attribute push profiles of SAML, including both Identity Provider (IdP) and Service Provider (SP) components. Polaris can act as a service provider and import the user from a Shibboleth to allow a single sign-on login.
## Configuration
To use Polaris together with Shibboleth, several things need to be configured. First, ensure that Polaris is successfully installed and operational. Verify its functionality and stability before proceeding with integration. You should be able to login with the database users.
### Generate Service Provider Information
Polaris automatically starts a service provider service. You can access the metadata of polaris `https://host/saml2/meta`. The metadata is generated by the public and private key from the configuration file.
Download the file and add the service provider information to your shibboleth system.
Example of the metadata file:
```xml
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" validUntil="2043-10-27T21:06:57.986716Z" cacheDuration="P7300D" entityID="https://polaris.digitallearning.gmbh/saml2/meta" ID="ONELOGIN_cfce9f8073759d0b20d49a98dfb2e5b87a69718f">
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"/>
<ds:Reference URI="#ONELOGIN_cfce9f8073759d0b20d49a98dfb2e5b87a69718f">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>Jpeg9HeGiHTAMCvG6jR2Cjmvd8xSZOZbE8SRyGiTgNw=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue></ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate></ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<md:SPSSODescriptor AuthnRequestsSigned="true" WantAssertionsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:KeyDescriptor use="signing">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate></ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:KeyDescriptor use="encryption">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate></ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://polaris.digitallearning.gmbh/saml2/acs" index="1"/>
</md:SPSSODescriptor>
<md:Organization>
<md:OrganizationName xml:lang="de">Polaris Rights Engine</md:OrganizationName>
<md:OrganizationName xml:lang="en">Polaris Rights Engine</md:OrganizationName>
<md:OrganizationDisplayName xml:lang="de">Polaris Rights Engine</md:OrganizationDisplayName>
<md:OrganizationDisplayName xml:lang="en">Polaris Rights Engine</md:OrganizationDisplayName>
<md:OrganizationURL xml:lang="de">https://www.digitallearning.gmbh</md:OrganizationURL>
<md:OrganizationURL xml:lang="en">https://www.digitallearning.gmbh</md:OrganizationURL>
</md:Organization>
<md:ContactPerson contactType="technical">
<md:GivenName>Service Desk</md:GivenName>
<md:EmailAddress>mailto:support@digitallearning.gmbh</md:EmailAddress>
</md:ContactPerson>
<md:ContactPerson contactType="support">
<md:GivenName>Service Desk</md:GivenName>
<md:EmailAddress>mailto:support@digitallearning.gmbh</md:EmailAddress>
</md:ContactPerson>
<md:ContactPerson contactType="administrative">
<md:GivenName>Service Desk</md:GivenName>
<md:EmailAddress>mailto:support@digitallearning.gmbh</md:EmailAddress>
</md:ContactPerson>
</md:EntityDescriptor>
```
### Add Shibboleth meta information
Next, we'll incorporate the metadata pertaining to the Identity Provider (IdP) into Polaris. The IdP generates an XML file that needs to be integrated into Polaris. Notably, Polaris comes preloaded with a sample IdP information file. This generated XML file from the IdP needs to be appended or replaced within Polaris to establish the necessary connection and authentication protocols.
The file looks like the following example:
```xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<EntityDescriptor entityID="https://aai-test-v3.ruhr-uni-bochum.de/idp/shibboleth" xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:idpdisc="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" xmlns:init="urn:oasis:names:tc:SAML:profiles:SSO:request-init" xmlns:mdattr="urn:oasis:names:tc:SAML:metadata:attribute" xmlns:mdrpi="urn:oasis:names:tc:SAML:metadata:rpi" xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui" xmlns:remd="http://refeds.org/metadata" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:saml1md="urn:mace:shibboleth:metadata:1.0" ID="DFN-AAI-Test_20230208221256" Name="https://www.aai.dfn.de/DFN-AAI-Test" validUntil="2023-02-14T22:12:56Z">
<Extensions>
<mdrpi:RegistrationInfo registrationAuthority="https://www.aai.dfn.de" registrationInstant="2016-09-15T07:04:09Z">
<mdrpi:RegistrationPolicy xml:lang="de">https://www.aai.dfn.de/teilnahme/</mdrpi:RegistrationPolicy>
<mdrpi:RegistrationPolicy xml:lang="en">https://www.aai.dfn.de/en/join/</mdrpi:RegistrationPolicy>
</mdrpi:RegistrationInfo>
</Extensions>
<IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<Extensions>
<saml1md:Scope regexp="false">ruhr-uni-bochum.de</saml1md:Scope>
<mdui:UIInfo>
<mdui:DisplayName xml:lang="de">Ruhr-Universität Bochum TEST-IDP-v3</mdui:DisplayName>
<mdui:DisplayName xml:lang="en">Ruhr-Universitaet Bochum TEST-IDP-v3</mdui:DisplayName>
<mdui:Description xml:lang="de">Test-IdP der Ruhr-Universität Bochum für die Shibboleth v3 Migration</mdui:Description>
<mdui:Description xml:lang="en">Ruhr-Universitaet Bochum Test-IdP for Shibboleth v3 migration</mdui:Description>
<mdui:Logo height="102" width="102">https://aai.ruhr-uni-bochum.de/idp/images/logo/logo-rub-102.gif</mdui:Logo>
<mdui:Logo height="16" width="16">https://www.ruhr-uni-bochum.de/themes/custom/rub/favicon.ico</mdui:Logo>
</mdui:UIInfo>
</Extensions>
<KeyDescriptor>
<ds:KeyInfo>
<ds:KeyName>aai-test-v3.ruhr-uni-bochum.de</ds:KeyName>
<ds:X509Data>
<ds:X509SubjectName></ds:X509SubjectName>
<ds:X509Certificate></ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</KeyDescriptor>
<ArtifactResolutionService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://aai-test-v3.ruhr-uni-bochum.de/idp/profile/SAML2/SOAP/ArtifactResolution" index="2"/>
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://aai-test-v3.ruhr-uni-bochum.de/idp/profile/SAML2/POST/SLO"/>
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://aai-test-v3.ruhr-uni-bochum.de/idp/profile/SAML2/POST-SimpleSign/SLO"/>
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://aai-test-v3.ruhr-uni-bochum.de/idp/profile/SAML2/Redirect/SLO"/>
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://aai-test-v3.ruhr-uni-bochum.de/idp/profile/SAML2/SOAP/SLO"/>
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://aai-test-v3.ruhr-uni-bochum.de/idp/profile/SAML2/POST/SSO"/>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://aai-test-v3.ruhr-uni-bochum.de/idp/profile/SAML2/POST-SimpleSign/SSO"/>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://aai-test-v3.ruhr-uni-bochum.de/idp/profile/SAML2/Redirect/SSO"/>
</IDPSSODescriptor>
<AttributeAuthorityDescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<Extensions>
<saml1md:Scope regexp="false">ruhr-uni-bochum.de</saml1md:Scope>
</Extensions>
<KeyDescriptor>
<ds:KeyInfo>
<ds:KeyName>aai-test-v3.ruhr-uni-bochum.de</ds:KeyName>
<ds:X509Data>
<ds:X509SubjectName></ds:X509SubjectName>
<ds:X509Certificate></ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</KeyDescriptor>
<AttributeService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://aai-test-v3.ruhr-uni-bochum.de/idp/profile/SAML2/SOAP/AttributeQuery"/>
</AttributeAuthorityDescriptor>
<Organization>
<OrganizationName xml:lang="de">e200</OrganizationName>
<OrganizationName xml:lang="en">e200</OrganizationName>
<OrganizationDisplayName xml:lang="de">Ruhr-Universität Bochum</OrganizationDisplayName>
<OrganizationDisplayName xml:lang="en">Ruhr-Universität Bochum</OrganizationDisplayName>
<OrganizationURL xml:lang="de">http://www.ruhr-uni-bochum.de</OrganizationURL>
<OrganizationURL xml:lang="en">http://www.ruhr-uni-bochum.de</OrganizationURL>
</Organization>
<ContactPerson contactType="other" remd:contactType="http://refeds.org/metadata/contactType/security">
<GivenName>AAI</GivenName>
<SurName>RUB</SurName>
<EmailAddress>mailto:aai@ruhr-uni-bochum.de</EmailAddress>
</ContactPerson>
<ContactPerson contactType="support">
<GivenName>AAI</GivenName>
<SurName>RUB</SurName>
<EmailAddress>mailto:aai@ruhr-uni-bochum.de</EmailAddress>
</ContactPerson>
<ContactPerson contactType="technical">
<GivenName></GivenName>
<SurName></SurName>
<EmailAddress></EmailAddress>
</ContactPerson>
</EntityDescriptor>
```
The file must be placed in the static folder of Polaris. If you use docker, you can mount the file using the volume pattern, e.g.:
```json
volumes:
- "./shibboleth.xml:/usr/src/app/static/shibboleth.xml"
```
### Configure additional attributes
You might need to set up the attribute mapping for the Shibboleth user. This involves configuring options by overriding the default values for the following attributes:
```json
SSO_USERNAME=urn:oid:0.9.2342.19200300.100.1.1 # uid
SSO_EMAIL=urn:oid:0.9.2342.19200300.100.1.3 # mail
SSO_FORENAME=urn:oid:2.16.840.1.113730.3.1.241 # givenName
SSO_SURNAME=urn:oid:2.16.840.1.113730.3.1.241 # sn
SSO_DISPLAY_NAME=urn:oid:2.16.840.1.113730.3.1.241 # displayName
```
### Debug shibboleth configuration
We've introduced a debug page specifically designed to troubleshoot issues related to Shibboleth or other SAML2 Identity Provider (IdP) systems. Access this page via the following link: `https://host/sso-dev`
We strongly advise hiding this page in a production environment to prevent unauthorized access or potential security vulnerabilities.
\ No newline at end of file
......@@ -9,7 +9,8 @@ theme:
nav:
- Rights Engine: rights_engine.md
- provider Schema: provider_schema.md
- Shibboleth: shibboleth.md
- Provider Schema: provider_schema.md
- Analytics Engine: analytics_engine.md
- Dashboard: dashboard.md
- Deployment: deployment.md
......
......@@ -206,6 +206,8 @@ EMAIL_HOST_USER = env("EMAIL_HOST_USER")
EMAIL_HOST_EMAIL = env("EMAIL_HOST_EMAIL", default=EMAIL_HOST_USER)
EMAIL_HOST_PASSWORD = env("EMAIL_HOST_PASSWORD")
CELERY_BROKER_URL = env("CELERY_BROKER_URL")
# Learning Record Store (LRS) MongoDB connection string
......@@ -223,6 +225,14 @@ JWT_AUTH = {
SESSION_COOKIE_AGE = 36000
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
# SSO
SP_HOST = env("SP_HOST") # FQDN of your SP
IDP_META_URL = env("IDP_SERVER") + "/idp/shibboleth" # production
IDP_LOGOUT_URL = env("IDP_LOGOUT_URL", default=env("IDP_SERVER") + "/idp/profile/Logout") # web page for IDP logout (might initiate SLO)
ATTRIBUTE_USERNAME = env("SSO_USERNAME","urn:oid:0.9.2342.19200300.100.1.1") # "uid"
ATTRIBUTE_EMAIL = env("SSO_EMAIL","urn:oid:0.9.2342.19200300.100.1.3") # "mail"
ATTRIBUTE_FORENAME = env("SSO_FORENAME","urn:oid:2.16.840.1.113730.3.1.241") # "givenName"
ATTRIBUTE_SURNAME = env("SSO_SURNAME","urn:oid:2.16.840.1.113730.3.1.241") # "sn"
ATTRIBUTE_DISPLAY_NAME = env("SSO_DISPLAY_NAME","urn:oid:2.16.840.1.113730.3.1.241") # displayName
\ No newline at end of file
renderingOptions:
submitButtonLabel: Absenden
type: Form
identifier: anmeldungLMSPrimarFormularDL
label: 'Anmeldung LMS Primar Formular (DL)'
prototypeName: standard
finishers:
-
options:
subject: 'Bewerbungsformular Lesen macht stark'
recipients:
benjamin.ledel@digitallearning.gmbh: 'Benjamin Ledel'
senderAddress: '{email-1}'
senderName: '{NameSchule}'
replyToRecipients:
benjamin.ledel@digitallearning.gmbh: 'Benjamin Ledel'
addHtmlPart: false
attachUploads: false
translation:
language: Standard
useFluidEmail: false
title: ''
identifier: EmailToReceiver
-
options:
message: 'Vielen Dank, Ihre Daten wurden gespeichert.'
contentElementUid: ''
templateRootPaths:
1644496688: 'EXT:bildungsportal/Resources/Private/Templates/Form/Confirmation/'
identifier: Confirmation
renderables:
-
renderingOptions:
previousButtonLabel: 'Vorherige Seite'
nextButtonLabel: 'Nächster Schritt'
type: Page
identifier: page-1
label: 'Bewerbungsformular „Lesen macht stark Niedersachsen Primarbereich“'
renderables:
-
defaultValue: ''
type: Text
identifier: NameSchule
label: 'Name der Schule'
properties:
fluidAdditionalAttributes:
required: required
validators:
-
identifier: NotEmpty
-
defaultValue: ''
type: Text
identifier: StrasseHausnummer
label: 'Straße & Hausnummer'
properties:
fluidAdditionalAttributes:
required: required
validators:
-
identifier: NotEmpty
-
defaultValue: ''
type: Text
identifier: PLZ
label: 'Postleitzahl'
properties:
fluidAdditionalAttributes:
required: required
validators:
-
identifier: NotEmpty
-
defaultValue: ''
type: Text
identifier: text-3
label: 'Ort'
properties:
fluidAdditionalAttributes:
required: required
validators:
-
identifier: NotEmpty
-
defaultValue: ''
type: Text
identifier: textarea-2
label: Schulnummer
properties:
validationErrorMessages:
-
code: 1221563685
message: 'Bitte geben Sie eine gültige Schulnummer ein.'
-
code: 1221561046
message: 'Bitte geben Sie eine gültige Schulnummer ein.'
fluidAdditionalAttributes:
min: '1000'
max: '99999'
required: required
validators:
-
options:
minimum: '1000'
maximum: '99999'
identifier: NumberRange
-
identifier: NotEmpty
-
defaultValue: ''
type: Text
identifier: text-4
label: 'RLSB (BS, H, LG, OS)'
properties:
fluidAdditionalAttributes:
required: required
validators:
-
identifier: NotEmpty
-
defaultValue: ''
type: Text
identifier: text-5
label: 'Landkreis'
properties:
fluidAdditionalAttributes:
required: required
validators:
-
identifier: NotEmpty
-
defaultValue: ''
type: Email
identifier: email-1
label: E-Mail-Adresse Sekretariat (bitte keine Privatadresse)
properties:
validators:
-
identifier: EmailAddress
-
identifier: NotEmpty
-
type: GridRow
identifier: gridrow-8
label: 'Grid: Zeile'
renderables:
-
defaultValue: ''
properties:
fluidAdditionalAttributes:
step: 1
required: required
validationErrorMessages:
-
code: 1221560910
message: 'Bitte eine Ziffer wählen.'
-
code: 1221560718
message: 'Bitte eine Ziffer wählen.'
-
code: 1347992400
message: 'Bitte eine Ziffer wählen.'
-
code: 1347992453
message: 'Bitte eine Ziffer wählen.'
type: Number
identifier: number-1
label: 'Voraussichtliche Schüler:innen-Zahl im kommenden 1. Jahrgang:'
validators:
-
identifier: Number
-
identifier: NotEmpty
-
type: Checkbox
identifier: checkbox-1
label: 'Die Zustimmung des Schulvorstands wurde eingeholt.'
-
type: Checkbox
identifier: checkbox-2
label: 'Die Zustimmung der Gesamtkonferenz wurde eingeholt.'
-
type: Checkbox
identifier: checkbox-3
label: 'Fehlende Zustimmungen werden nachträglich eingeholt.'
-
type: Checkbox
identifier: checkbox-4
label: 'Eine Vertreterin/ein Vertreter unserer Schule hat an einer der Informationsveranstaltungen zu Lesen macht stark Niedersachsen teilgenommen.'
-
type: Checkbox
identifier: checkbox-5
label: 'Diese Anmeldung ist direkt durch die Schulleitung oder im Auftrag dieser erfolgt.'
-
properties:
text: 'Ich habe zur Kenntnis genommen, dass unsere Schule im kommenden Schuljahr von der Teilnahme an LMS ausgeschlossen wird, wenn die gemeldeten Lehrkräfte oder deren Vertretung nicht in der ersten Modulveranstaltung anwesend sind.'
type: StaticText
identifier: statictext-2
label: ''
\ No newline at end of file
......@@ -36,7 +36,7 @@ def get_idp_runtime_info(meta_url):
# parse the xml
try:
parser1 = etree.XMLParser(encoding="utf-8", recover=True)
idp_meta = ElementTree.parse(os.path.join(BASE_DIR,'static/shibboleth_bochum.xml'))
idp_meta = ElementTree.parse(os.path.join(BASE_DIR,'static/shibboleth.xml'))
except Exception as e:
logger.error("Could not parse IDP meta.")
raise e
......
File moved
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment