-
Notifications
You must be signed in to change notification settings - Fork 75
Mobile DPoP FIDO Authn
Michael Schwartz edited this page Jul 30, 2024
·
19 revisions
A design for a first party mobile application that leverages dynamic client registration (DCR), DPoP access tokens, and FIDO user authenticaiton. In Jans Auth Server, we would end up having at least three long lived records: one for the person, one for each device (client), and one for each FIDO credential.
This spec leverages the following IETF drafts
- OAuth 2.0 for First-Party Native Applications
- The Use of Attestation in OAuth 2.0 Dynamic Client Registration.
- OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)
title Mobile Authentication with DPoP and FIDO
autonumber
actor Person
participant App
participant Device
participant Device Keystore
participant Auth Server
participant Fido2 Server
participant API
participant App Store
fontfamily mono
autonumber 1
participant ChangeMe1
critical Download App
Person->App Store: Search for App
Device<->App Store: Install App
end
critical Dynamic Client Registration
Person->App: Start App
App<->Device: Get Device info
Device<->Device Keystore: Generate keys
Device->Auth Server: /register : Send public key\nfor client authn + app attestation
Auth Server->Auth Server: validate\napp attestation
alt attestation good
Auth Server->Device: client registration response
else attestation bad
Auth Server->Device: 400 {"error":"bad_attestation",\n"error_description": "Server verification of app attestation failed"}
end
end
alt Enrollment (First time using app)
Person<->App: uid / pw\n(future: NFC card,\n or verifiable credential)
App->Auth Server: POST /authz-challenge \n {"acr_values":"pw-enroll",\n "client_id":"1234",\n "scope":"authz-challenge"}
Auth Server->Auth Server: validate pw
App<->Fido2 Server: FIDO biometric enrollment
Auth Server->App: code
end
alt Call API
App->Auth Server: POST /authz-challenge \n {"acr_values":"fido2",\n "client_id":"1234",\n "scope":"authz-challenge"}
Auth Server->App: 403 Forbidden\n {"error": "authorization_required",\n "device_session":"uY29tL2F1dGhlbnRpY"}
loop authn required because id_token invalid
App->Device: Android / iOS\nFIDO API
Person<->Device: present biometric
App->Fido2 Server: /fido 2: Find user by keyHandle+RP, check fido2 response signature
Fido2 Server-> App: Mint token with type fido2
App->Auth Server: POST /authz-challenge\n {"acr_values":"fido2",\n "client_id":"1234",\n "scope":"xyz",\n "device_session":"uY29tL2F1dGhlbnRpY",\n "fido2_token":"9d2d-848919ce89c9"}
Auth Server->Auth Server: Verify fido2 token
Auth Server->App: code
end
App->Auth Server: /token\ncode + private key authn
Auth Server->App: Issue DPoP access_token
App->API: access_token
end
title DPoP sender-constraint access_token and refresh_token
autonumber 1
note right of RP: Authorization Code Flow
RP->AS: Request authorization with dpop_jtk
AS->AS: dpop_jkt saved for authorization code
AS->RP: Return authorization code
note right of RP: Token Request
RP->AS: Request token with DPoP JWT
AS->AS: Validates DPoP JWT
AS->AS: Validates dpop_jkt against DPoP JWT if it's authz code
AS->AS: Creates access_token bound to public key cnf/jkt
note right of AS: if AT is bearer cnf/jkt is available via introspection
AS->RP: Returns DPoP-bound access_token with cnf/jkt (response token_type=DPoP)
RP->RS: Request resource with access_token and DPoP JWT (with "ath" - AT hash)
RS->RS: Validates access_token against DPoP (public key match cnf/jkt)
RS->RS: Validates DPoP against access_token (access_token hash in DPoP "ath")
RS->RP: Return protected resource