Feide-innlogging
Beskrivelse
For å få Feide-innlogging brukes tjenesten Dataporten, som er en OAuth 2.0-provider som autentiserer brukeren via Feide.
Django er konfigurert til å autentisere via OAuth 2.0 ved hjelp av biblioteket django-allauth (se Django tilleggspakker), og trenger ikke noen spesiell kjennskap til Feide utover de tilpasningene som er beskrevet under.
Funksjonaliteten er avhengig av innstillingen USE_FEIDE_AUTH
.
Konfigurasjon av Feide-innlogging
For at Feide-innlogging skal fungere må det defineres en applikasjon i Dataporten. Dette gjøres via Dataporten Dashboard.
Se Registering and managing applications, spesielt Managing applications for framgangsmåte.
Når applikasjonen registreres trengs disse opplysningene:
Basic info
Grunnleggende innstillinger:
Navn: Passende beskrivelse, f.eks «Wagtail utviklingsmiljø» for testinstallasjoner.
Redirect URI: Vil typisk være
http://localhost:8000/accounts/dataporten/login/callback/
for testinstallasjoner oghttps://wagtail.math.ntnu.no/accounts/dataporten/login/callback/
for produksjonsinstansen.Require user interaction: Ja
Client type: Confidential
Auth providers
Innstillinger om hvilke brukere som skal kunne logge inn:
Accept all providers: Nei
Miscellaneous login providers: Ingen
Social network: Ingen
Åpne for alle i utdanningssektoren: Ja
Permissions
Hvilken informasjon vi ber om å få om brukeren fra Feide. Vi trenger kun:
E-post (email): Brukerens e-postadresse.
Bruker-ID (userid): Brukerens ID i dataporten.
Feide-navn (userid-feide): Brukerens identifikator i Feide. Tilsvarende
eduPersonPrincipalName
.
OAuth details
Når applikasjonen er opprettet finner man applikasjonens OAuth credentials under menyvalget «OAuth details»:
Client ID:
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Client Secret:
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Disse må legges inn i Django slik:
Gå til /django-admin/
Logg inn som brukeren du opprettet med
./manage.py createsuperuser
Opprett et nytt Social applications-objekt med følgende innstillinger:
Provider: Dataporten
Name: Dataporten
Client id: Client ID fra Dataporten
Secret key: Client Secret fra Dataporten
Sites: Dette nettstedet (typisk
localhost
ellerwagtail.math.ntnu.no
)
Nettstedet som brukes er nødt til å ha SITE_ID = 1
(dette er hardkodet i src/website/settings.py
),
så det er enklest å endre navn på default site example.com
til ønsket navn,
i stedet for å legge inn en ny site i Django admin.
Tilpasninger av django-allauth
Innstillinger
Django-allauth sender i utgangspunktet epost til nye brukerkontoer,
slik at de kan verifisere/bekrefte epostadressen sin.
Dette er disablet ved hjelp av innstillingene
ACCOUNT_EMAIL_VERIFICATION = 'none'
og
SOCIALACCOUNT_EMAIL_VERIFICATION = 'none'
i Django settings.
For at brukeren skal bli logget rett inn uten å måtte bekrefte at man
ønsker å logge inn via en tredjepartstjeneste (Dataporten) er
SOCIALACCOUNT_LOGIN_ON_GET = True
satt.
Tilpassing av hvordan nye brukerkontoer opprettes
I utgangspunktet må en ny bruker logge inn én gang slik at brukerkontoen blir opprettet, før det er mulig å tildele redigeringsrettigheter. Vi ønsker å kunne opprette brukerkontoer med riktige rettigheter på forhånd, slik at alt er klart til bruk første gang vedkommende logger inn i Wagtail.
Hvis vi oppretter en Django-brukerkonto med et gitt Feide-brukernavn på forhånd, vet ikke django-allauth (og kan ikke vite/anta) at dette er snakk om samme bruker, og django-allauth vil i utgangspunktet da opprette en annen Django-brukerkonto med annet/tilfeldig/udefinert brukernavn som er koblet til Feide-kontoen.
Vi har bedt django-allauth om å gjøre en slik antakelse - ved første gangs innlogging blir Feide-kontoen koblet mot eksisterende Django-konto hvis det finnes en Django-konto med samme brukernavn som Feide-kontoen.
Dette er gjort ved å bruke vår egen SocialAccountAdapter
feide.adapter.SocialAccountAdapter
.
Denne arver fra allauth.socialaccount.adapter.DefaultSocialAccountAdapter
men overstyrer logikken rundt oppretting av brukerkonto.
Hvilken adapter som skal brukes styres av innstillingen
SOCIALACCOUNT_ADAPTER
i Django settings.
Uønsket funksjonalitet i django-allauth
Django-allauth har ekstra funksjonalitet som vi ikke ønsker å bruke:
signup: Det er mulig å opprette lokal brukerkonto direkte, uten å gå via Feide-innlogging.
passordendring: En bruker kan sette lokalt passord på den lokale django-brukerkontoen sin, og dermed klare å logge inn selv om Feide-brukerkontoen blir stengt.
Vi ønsker ikke slike bakveier inn i systemet, og har disablet disse funksjonene.
Django-allauth har ingen mekanisme for å disable disse
(dokumentasjonen nevner ingen ting om denne problemstillingen),
så vi har brukt en workaround som kan komme til å slutte å fungere i nyere versjoner
av django-allauth. I stedet for å la vår src/website/urls.py
inkludere hele
allauth.urls
, inkluderer vi kun de entrypointene som har med dataporten å gjøre.
Dette gjøres via vår egen modul feide.urls
.
En annen mulig løsning kunne vært å inkludere hele allauth.urls
for så å
overstyre/maskere de entrypointene vi ikke ønsker skal bli brukt. Denne måten
er også sårbar for eventuelle endringer i nye versjoner av django-allauth (som
tilføyer nye eller bytter navn på de endepunktene vi har overstyrt.
Det er derfor lagt til automatiserte tester i src/feide/tests.py
som sjekker at
alt fremdeles er OK etter eventuelle oppgraderinger av django-allauth:
Testene sjekker at de endepunktene og viewene vi har overstyrt faktisk er de som brukes,
og at det ikke har dukket opp nye endepunkter under /accounts
som ikke er maskert
(bortsett fra /accounts/dataporten
).
Se src/feide/tests.py
.
Inn- og utlogging
Utlogging fra Dataporten er ikke implementert i django-allauth.
Vi har derfor implementert noen egne views i feide
-modulen:
feide.views.logout
: Logger ut brukeren på riktig måte. Se https://docs.feide.no/developer_oauth/technical_details/oauth_authentication.html#logoutfeide.views.login
: Redirigerer brukeren til riktig innloggings-URL avhengig av om Feide-innlogging er påskrudd eller ikke. Dette viewet brukes for tiden ikke av noen templates.
Logging av inn/utlogginger og feilede innloggingsforsøk gjøres via
signalhåndterere/callbacks i feide.signals
.
Disse installeres via AppConfig-klassen i feide.apps
,
se src/feide/__init__.py
.