-
Osnovni preduvjet za korištenje Single Sign-On (SSO) autentikacije u Django projektu je instalacija i konfiguracija paketa djangosaml2 koja se može obaviti prateći detaljne upute na stranici https://bitbucket.org/lgs/djangosaml2
Referentne, testirane te u ovim uputama preporučene verzije potrebnih paketa su:
- xmlsec1 1.2.18 (openssl)
- pysaml2==0.4.3
- djangosaml2==0.10.0
U paketu
pysaml2 0.4.3
potrebno je obaviti sljedeću promjenu u datoteci binding.py:# komentirati sljedeći redak # login_url = "?".join([location, urllib.urlencode(args)]) # i umjesto njega dodati sljedeća dva retka join_symbol = "&" if "?" in location else "?" login_url = join_symbol.join([location, urllib.urlencode(args)])
U nastavku su navedene modifikacije koraka navedenih uputama u točki 1. te dodatni koraci koje je potrebno obaviti kako bi autentikacija bila uspješna.
-
Postojeći autentikacijski sustav preporučeno je u potpunosti zamijeniti sa SSO autentikacijom, pa
'djangosaml2.backends.Saml2Backend'
treba biti jedini autentikacijski backend definiran usettings.py
:AUTHENTICATION_BACKENDS = ( 'djangosaml2.backends.Saml2Backend', )
-
Postaviti URL-ove na koji će se usmjeriti korisnika nakon uspješne prijave odnosno odjave. Postavka
LOGIN_REDIRECT_URL
se koristi samo ukoliko korisnik nije došao do formulara za prijavu pokušajem pristupa adresi u zaštićenom dijelu stranica, u tom slučaju se nakon uspješne prijave korisnik proslijeđuje na željenu adresu:LOGIN_REDIRECT_URL = '/' LOGOUT_REDIRECT_URL = '/'
-
Ostaviti preddefiniranu vrijednost za postavku koji definira polje u modelu
User
nad kojim će se nakon uspješne autentikacije od strane AAI@EduHr sustava obaviti upit kako bi se pronašao odgovarajući Django korisnik:SAML_DJANGO_USER_MAIN_ATTRIBUTE = 'username'
-
Ukoliko je korisnik uspješno autenticiran od strane AAI@EduHr sustava, a upitom u model
User
u polje definirano postavkomSAML_DJANGO_USER_MAIN_ATTRIBUTE
nije pronađen odgovarajući korisnik tada će se kreirati novi Django korisnik i to u ovisnosti o slijedećoj postavci:SAML_CREATE_UNKNOWN_USER = True
Ukoliko želite veću kontrolu prilikom odluke o stvaranju novih Django korisnika pogledajte nekoliko opcija u odjeljku Kreiranje Django korisnika.
-
Nakon autentikacije Django korisnika
Saml2Backend
može unijeti odnosno osvježiti podatke o korisniku iz podataka iz imenika odnosno atributa koji su isporučeni od strane AAI@EduHr sustava prilikom same autentikacije.Kako bi definirali koji će atributi biti isporučeni pogledajte odjeljak u ovim uputama u kojem se opisuje postupak registracije aplikacije u sustav AAI@EduHr.
Nadalje, potrebno je definirati u koja će polja modela
User
isporučeni atributi biti upisivani. Slijedeće vrijednosti možete koristiti kao početne:SAML_ATTRIBUTE_MAPPING = { 'hrEduPersonUniqueID': ('username', ), 'mail': ('email', ), 'givenName': ('first_name', ), 'sn': ('last_name', ), }
Prema djangosaml2 uputama isporučeni atributi se mogu automatski upisivati i u polja modela u kojem je definiran profil korisnika, međutim takav način osvježavanja profila bi trebalo izbjegavati s obzirom da koristi funkcionalnosti koje nisu podržane u novim verzijama Djanga kao što to opisuje ovaj issue.
Osvježavanje drugih modela korištenjem isporučenih atributa kao i selektivno osvježavanje modela
User
može se ostvariti definiranjem handler-a zapre_user_save
signal kako je opisano u uputama za djangosaml2. Ukoliko radite update modela koji nijeUser
potrebno je pozvati isave
metodu. -
Ako koristite Django verziju 1.5 ili višu tada je potrebno kopirati sve template-e iz djangosaml2 aplikacije koji koriste
url
template tag i modificirati ih na način da imaju navodnike oko prvog parametra.Kako je navedeno i u službenoj dokumentaciji, Django od verzije 1.5 ne podržava implicitno pretvaranje prvog argumenta
url
template tag-a u string. Isto je napomenuto i u zasada nerješenoj razvojnoj stavci djangosaml2 paketa.
Paket djangosaml2 u pozadini koristi paket pysaml koji obavlja većinu posla vezanog uz kreiranje saml paketa i komunikacije.
Primjer konfiguracije tog paketa prilagođen sustavu AAI@EduHr koji se definira u datoteci settings.py
dan je u nastavku:
from os import path
import saml2
BASEDIR = path.dirname(path.abspath(__file__))
SAML_CONFIG = {
'xmlsec_binary': '/usr/bin/xmlsec1',
'entityid': 'http://localhost:8000/saml2/metadata/',
'service': {
'sp': {
'name': 'Django sample SP',
'endpoints': {
# url and binding to the assetion consumer service view
# do not change the binding or service name
'assertion_consumer_service': [
('http://localhost:8000/saml2/acs/',
saml2.BINDING_HTTP_POST),
],
# url and binding to the single logout service view
# do not change the binding or service name
'single_logout_service': [
('http://localhost:8000/saml2/ls/',
saml2.BINDING_HTTP_REDIRECT),
],
},
},
},
# where the remote metadata is stored
'metadata': {
'remote': [
{
"url": "https://login.aaiedu.hr/sso/module.php/aggregator/?id=aaieduhr_fedlab&mimetype=application" # lab
#"url": "https://login.aaiedu.hr/sso/idp_riteh.xml", # production
"cert": "idp.crt"
}
],
#'local': [path.join('path', 'to', 'remote_metadata.xml')], # local xml alternative
},
# set to 1 to output debugging information
#'debug': 1,
# certificate
'key_file': path.join(BASEDIR, 'key.pem'), # private part
'cert_file': path.join(BASEDIR, 'cert.pem'), # public part
# own metadata settings used by make_metadata.py
'contact_person': [
{
'given_name': 'Name',
'sur_name': 'Surname',
'company': 'Company',
'email_address': 'mail@example.com',
'contact_type': 'technical',
},
{
'given_name': 'Name',
'sur_name': 'Surname',
'company': 'Company',
'email_address': 'mail@example.com',
'contact_type': 'administrative',
},
],
# you can set multilanguage information here
'organization': {
'name': [('Company', 'en'), ],
'display_name': [('CO', 'en'), ],
'url': [('http://www.example.com', 'en'), ],
},
}
Službena dokumentacija svih parametara može se naći na ovoj stranici.
Ono što slijedi su potrebne modifikacije te standardne konfiguracije:
-
Provjerite ako je put do datoteke
xmlsec1
ispravno upisan u parametar'xmlsec_binary'
. Put možete naći naredbomwhich xmlsec1
. -
Vrijednosti parametara
entityid
,assertion_consumer_service
isingle_logout_service
potrebno je unijeti na način da se "localhost:8000" zamijeni s nazivom i portom poslužitelja na kojem se aplikacija nalazi. -
Sadržaj datoteke
remote_metadata.xml
dohvaća se s adresehttps://login.aaiedu.hr/sso/idp_riteh.xml
za produkciju odnosnohttps://login.aaiedu.hr/sso/module.php/aggregator/?id=aaieduhr_fedlab&mimetype=application
za lab. Certifikatidp.crt
u kojem je javni ključ kojim verificiramo datoteku je potrebno dohvatiti s adresehttps://login.aaiedu.hr/sso/module.php/saml/idp/certs.php/idp.crt
. Dodatno je potrebno osigurati prisutnost TERENA SSL CA certifikata u datoteci/path/to/lib/python2.7/site-packages/httplib2/cacerts.txt
. Lanac certifikata može se dobiti naredbomopenssl s_client -showcerts -connect login.aaiedu.hr:443 </dev/null
, iz kojeg je potrebno kopirati samo TERENA SSL CA certifikat.-
Ukoliko verifikacija datoteke ne funkcionira moguće zaobići udaljeni dohvat i datoteku dohvaćati koristeći cron npr.
0 7 * * * wget --ca-directory=/path/to/lib/python2.7/site-packages/httplib2 -O ~/path/to/remote_metadata.xml https://login.aaiedu.hr/sso/saml2/idp/metadata.php
te referencirati se na nju u postavkama koristeći:'metadata': { 'local': [path.join('path', 'to', 'remote_metadata.xml')], },
-
-
Što se tiče parametara
'key_file': path.join(BASEDIR, 'key.pem'), # private part 'cert_file': path.join(BASEDIR, 'cert.pem'), # public part
Sustav AAI@EduHr za sada još uvijek ne provjerava certifikat vaše aplikacije pa možete kreirati bilo kakav self signed certifikat i unijeti ga kao parametar.
Primjer kreiranja self signed certifikata:
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365000 -nodes
-
Za potrebe razvoja lokalno odnosno na Django razvojnom poslužitelju te za potrebe testiranja može se koristiti mockdjangosaml2 paket. Upute za instalaciju i konfiguriranje nalaze se na stranicama repozitorija.
-
Postaviti https.
Tijekom prijave se u nekim browserima (Firefox) javlja slijedeća poruka.
Although this page is encrypted, the information you have entered is to be sent over an unencrypted connection and could easily be read by a third party. Are you sure you want to continue sending this information?
Iako sigurnost nije dovedena u pitanje poruka ne izgleda lijepo. Mogući razlog je taj što AssertionConsumerServiceURL http://localhost:8000/saml2/acs/ ne koristi https protokol? TODO: provjeriti
Ukoliko želite kontrolu prilikom odluke o stvaranju novih Django korisnika, odnosno ne želite za svakog korisnika koji je uspješno autenticiran preko sustava AAI@EduHr automatski stvoriti novog Django korisnika tada postoji nekoliko opcija od kojih izdvajamo:
-
U projektu se definira novi backend kao podrazred
Saml2Backend
-a te u njemu definirati metoduis_authorized
koja treba vratitiTrue
iliFalse
u ovisnosti o atributima korisnika. Primjer u kojem se pristup omogućava samo djelatnicima Tehničkog fakulteta u Rijeci, odnosno samo za njih se, ukoliko je potrebno, stvaraju novi Django korisnici:from djangosaml2.backends import Saml2Backend class CustomSaml2Backend(Saml2Backend): def is_authorized(self, attributes, attribute_mapping): if attributes.get('hrEduPersonHomeOrg', [''])[0]=='riteh.hr' and \ attributes.get('hrEduPersonPrimaryAffiliation', [''])[0]=='djelatnik': return True return False
U ovom slučaju postavka
SAML_CREATE_UNKNOWN_USER
ostaje definirana kaoTrue
. Takodjer, ne zaboravite u postavciAUTHENTICATION_BACKENDS
zamijeniti postojeći backend s novim. -
Postavite vrijednost postavke
SAML_CREATE_UNKNOWN_USER
na ˙False˙. U tom slučaju potrebno je za korisnike za koje se želi omogućiti pristup prethodno kreirati odgovarajuće Django korisnike nekom drugom metodom npr. kroz admin sučelje. Ti korisnici moraju imati korisničko ime koje odgovara'hrEduPersonUniqueID'
u LDAP bazi.
Osim prethodno navedenoga, trebat ćete i registrirati Vašu aplikaciju u sustavu AAI@EduHr te zatražiti kreiranje testnog elektroničkog identiteta.
Registracija aplikacije obavlja se putem Registra resursa koji se nalazi na adresi http://www.aaiedu.hr/aairr/
Nakon što se prijavite u Registar, kliknite na ikonicu "Resursi koji koriste SAML protokol" i zatim u prozoru koji će vam se otvoriti kliknite na gumb "Zatraži registraciju novog resursa".
Prilikom popunjavanja zahtjeva:
U izborniku Vrsta resursa trebate odabrati: test.
U polju SAML metapodaci trebate upisati slijedeće vrijednosti:
-
Jedinstveni identifikator resursa: treba odgovarati onome što ste u datoteci
settings.py
unijeli kao vrijednost parametra'entityid'
. -
AssertionConsumerService URL: treba odgovarati onome što ste u datoteci
settings.py
unijeli kao vrijednost parametra'assertion_consumer_service'
. -
SingleLogoutService URL: treba odgovarati onome što ste u datoteci
settings.py
unijeli kao vrijednost parametra'single_logout_service'
. -
Redirect Sign: false
-
Shema po kojoj se mapiraju atributi: niti jedna
-
Verzija SAML protokola koju servis koristi: 2.0
U polju "Označite atribute koje sustav AAI@EduHr treba isporučivati resursu" trebate odabrati isključivo minimalni set atributa koji je potreban za normalno funkcioniranje vaše aplikacije.
Popis svih atributa koje sustav AAI@EduHr može isporučiti vašoj aplikaciji naveden je na web stranici http://schema.aaiedu.hr/shema/
Ostatak forme popunite prema vlastitom nahođenju.
I na kraju, obzirom da se u ovoj fazi radi o testnoj aplikaciji, morat ćete zatražiti i kreiranje testnog elektroničkog identiteta putem web sučelja na adresi https://fed-lab.aaiedu.hr/zahtjev.php?show=zahtjev_identitet
@darbula, hvala ti, vrlo korisno, ako netko želi koristit AAI@EduHr Single Sign-On u Ruby on Rails aplikaciji, ovo može pomoći: https://gist.github.com/zmajstor/9c00c8a76faa73e6cf96