Salasanat ovat tilien tietoturvan heikoin lenkki. Ne voidaan kalastella, vuotaa, käyttää uudelleen tai unohtaa. Siksi lisäsimme tuen WebAuthn-pääsyavaimille (passkeys): tietojenkalastelua kestävälle, salasanattomalle tunnistautumistavalle, joka on sekä turvallisempi että kätevämpi.

Mitä pääsyavaimet ovat?

Pääsyavaimet ovat laitteellesi (puhelimeen, kannettavaan tai suojausavaimeen) tallennettuja kryptografisia tunnistetietoja, jotka korvaavat salasanat tunnistautumisessa. Ne perustuvat WebAuthn-standardiin (osa FIDO2:ta), ja niissä on monta etua:

  • Kestävät tietojenkalastelua: pääsyavaimet on sidottu sivuston verkkotunnukseen, joten niitä ei voi käyttää väärennetyillä sivustoilla
  • Ei vuotavia salaisuuksia: palvelimelle tallennetaan vain julkinen avain
  • Laitteeseen sidottuja: yksityinen avain ei koskaan poistu laitteeltasi
  • Biometrisesti suojattuja: yleensä Face ID:n, Touch ID:n tai Windows Hellon suojaamia
  • Synkronoituvat laitteiden välillä: nykyaikaiset alustat synkronoivat pääsyavaimet laitteiden välillä iCloud-, Google- tai Microsoft-tilin kautta

Toteutuksemme

Liitimme WebAuthn-pääsyavainten tuen olemassa olevaan django-allauth-pohjaiseen tunnistautumiskokonaisuuteemme ja tarjoamme sekä verkko- että mobiili-API-päätepisteet.

Rekisteröinnin kulku

Kun käyttäjä rekisteröi uuden pääsyavaimen, kulku etenee näin:

  1. Asiakas pyytää palvelimelta rekisteröintiasetukset
  2. Palvelin luo haasteen käyttäjän ja luottavan osapuolen tiedoilla
  3. Selaimen WebAuthn-rajapinta pyytää käyttäjää vahvistamaan (biometrisesti tai suojausavaimella)
  4. Asiakas lähettää tunnistetiedon takaisin palvelimelle
  5. Palvelin tarkistaa ja tallentaa julkisen avaimen
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# API endpoint to begin registration
class WebAuthnRegistrationOptionsView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        from allauth.mfa.webauthn.internal import auth as webauthn_auth

        # Generate credential creation options
        creation_options = webauthn_auth.begin_registration(
            request.user,
            passwordless=False  # Use as 2FA, not passwordless
        )

        return Response({
            "success": True,
            "creation_options": creation_options,
        })

Tunnistautumisen kulku

Kaksivaiheisessa tunnistautumisessa pääsyavaimella:

  1. Käyttäjä suorittaa ensisijaisen tunnistautumisen (käyttäjätunnus ja salasana tai kirjautuminen sosiaalisen median tilillä)
  2. Palvelin palauttaa haasteen WebAuthn-vahvistusta varten
  3. Selain pyytää pääsyavainta (biometrinen kosketus)
  4. Tunnistetieto tarkistetaan tallennettua julkista avainta vasten
  5. Käyttäjä on tunnistautunut kokonaan
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class WebAuthnVerifyView(APIView):
    def post(self, request):
        credential = request.data.get("credential")

        # Complete authentication and verify credential
        authenticator = webauthn_auth.complete_authentication(
            request.user,
            credential
        )

        # Record usage for security monitoring
        authenticator.last_used_at = timezone.now()
        authenticator.save()

        return Response({"success": True})

Pääsyavainten hallinta

Käyttäjät voivat hallita rekisteröityjä pääsyavaimiaan:

  • Listata kaikki pääsyavaimet rekisteröintipäivän ja viimeisimmän käytön kera
  • Nimetä pääsyavaimia uudelleen, jotta ne on helpompi tunnistaa (esim. “iPhone”, “MacBook”)
  • Poistaa pääsyavaimia (viimeisen tunnistautumistavan poistaminen on estetty)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class WebAuthnListView(APIView):
    def get(self, request):
        authenticators = Authenticator.objects.filter(
            user=request.user,
            type=Authenticator.Type.WEBAUTHN
        ).order_by("-created_at")

        return Response({
            "passkeys": [
                {
                    "id": auth.pk,
                    "name": auth.wrap().name,
                    "created_at": auth.created_at.isoformat(),
                    "last_used_at": auth.last_used_at.isoformat() if auth.last_used_at else None,
                }
                for auth in authenticators
            ]
        })

API-päätepisteet

REST-rajapintamme tarjoaa mobiilisovellukselle täyden WebAuthn-tuen:

PäätepisteMetodiKuvaus
/api/webauthn/register/options/GETHae rekisteröinnin haaste
/api/webauthn/register/complete/POSTViimeistele rekisteröinti
/api/webauthn/authenticate/options/GETHae tunnistautumisen haaste
/api/webauthn/verify/POSTTarkista tunnistetieto kaksivaiheista tunnistautumista varten
/api/webauthn/GETListaa rekisteröidyt pääsyavaimet
/api/webauthn/<id>/PATCHNimeä pääsyavain uudelleen
/api/webauthn/<id>/DELETEPoista pääsyavain

Tietoturvanäkökohdat

Palautuskoodit

Kun käyttäjä rekisteröi ensimmäisen tunnistautumistapansa (pääsyavaimen tai TOTP:n), luomme automaattisesti palautuskoodit. Näitä kertakäyttöisiä koodeja voi käyttää, jos kaikki muut tunnistautumistavat eivät ole käytettävissä:

1
2
if Authenticator.objects.filter(user=request.user).count() == 1:
    auto_generate_recovery_codes(request._request)

Lukkiutumisen estäminen

Käyttäjä ei voi poistaa viimeistä pääsyavaintaan, jos hänelle ei sen jälkeen jäisi yhtään kaksivaiheisen tunnistautumisen tapaa:

1
2
3
4
if not adapter.can_delete_authenticator(authenticator):
    return Response({
        "message": "Cannot delete - you must have at least one authentication method"
    }, status=400)

Valvonta

Seuraamme pääsyavainten käyttöä Datadog-mittareilla tietoturvan valvomiseksi:

1
2
3
increment("webauthn.registration.success")
increment("webauthn.verify.success")
increment("webauthn.verify.failed")

Selaintuki

WebAuthnia tukevat kaikki nykyaikaiset selaimet:

  • Chrome 67+
  • Firefox 60+
  • Safari 13+
  • Edge 79+
  • Chromen, Safarin ja Firefoxin mobiiliversiot

Vanhemmilla selaimilla käyttäjät voivat edelleen käyttää TOTP:ta (todennussovelluksia) tai palautuskoodeja.

Käyttökokemus

Pääsyavaimen lisääminen vie vain sekunteja:

  1. Siirry kohtaan Asetukset → Tietoturva → Kaksivaiheinen tunnistautuminen
  2. Napsauta Lisää pääsyavain
  3. Nimeä laitteesi (esim. “iPhone 15”)
  4. Tunnistaudu Face ID:llä, Touch ID:llä tai Windows Hellolla
  5. Valmista! Pääsyavaimesi on rekisteröity

Jatkossa kirjautumiseen riittää biometrinen vahvistus: ei salasanojen kirjoittamista eikä koodien kopioimista todennussovelluksista.

Miksi valitsimme pääsyavaimet

MenetelmäKalasteluriskiKäyttökokemusPalautus
SalasanatSuuriHeikko (unohtuvat, heikkoja)Nollaus sähköpostilla
Tekstiviesti-2FAKohtalainen (SIM-kortin kaappaus)KohtuullinenPuhelinnumero
TOTP-sovelluksetPieniKoodin syöttö käsinVarmuusavaimet
PääsyavaimetHyvin pieniErinomainenPalautuskoodit

Pääsyavaimet ovat tunnistautumisen tulevaisuus. Applen, Googlen ja Microsoftin alustat tukevat niitä jo, joten ne ovat lähes kaikkien käyttäjiemme ulottuvilla.


Valmis luopumaan salasanoista? Ota pääsyavaimet käyttöön tietoturva-asetuksissasi!