pow
pow copied to clipboard
WebAuthn and multi factor support
Add two factor support to Pow with at least OTP and FIDO U2F support.
Good primer for ensuring secure and useful two factor setup: https://medium.com/@stuartschechter/before-you-turn-on-two-factor-authentication-27148cc5b9a1
Edit: Here's some security considerations: https://shahmeeramir.com/4-methods-to-bypass-two-factor-authentication-2b0075d9eb5f
MFA auth
- WebAuthn
- OTP/TOTP
- Recovery codes
- E-mail/magic link
- Device authorization (in app)
Process
In general the MFA authentication process will go like this:
User ID & password --> MFA authorization --> Signed in
OR as passwordless:
User ID --> MFA authorization --> Signed in
This latter option could also be all on the same page for some of the above methods. The MFA methods can also be used for the registration process.
There should be a controller action for handling 2FA auth, and probably one for handling registration with 2FA. Maybe one for managing 2FA methods.
WebAuthn links
https://webauthn.guide/ https://auth0.com/blog/web-authentication-webauthn-overview-demo-tool/
Suggested Ecto schema
There're two ways to go about this. Embedded or separate table. Separate table may make it easier to not require user id, but it could be that the user id should just be set to generated_id if developers wish to login without user id with a randomly generated id that will be stored with the authenticator.
field :type, :string
field :nickname, :string
field :settings, :map
WebAuthn use case
WebAuthn allows for no user id and can be used for single authentication.
The WebAuthn will store at minimum the following data:
{
credential_id: "credential_id",
cose_key: "cose_key"
}
For no user id setup, the user id used for the authenticator could be a randomly generated id that's stored in the authenticator schema.
TOTP use case
TOTP can only be used for 2FA. The data stored would be the following:
{
issuer: "My Service",
otp_secret: "secret",
last_otp_at: "492039"
}
A WebAuthn library that could be tested with: https://github.com/tanguilp/wax
WebAuthn standard has been finalized by W3C!
We should consider a pure single factor Webauthn registration/authentication process where user id and password is not required (or user id is the the webauthn credential id(s). On top of this there will also be two factor.
I do think it’s the future of web authentication, far more than provider login.
From the elixirforum, there's a question on multiple user id field authentication:
I’m just a bit curious. ^^ Is it possible (or could it be) to pass a list of fields to
:user_id_field, so that user can authenticate through the field of their choice?defmodule MyApp.Users.User do use Ecto.Schema use Pow.Ecto.Schema, user_id_field: [:email, :pseudo, :phone] # ... end
This may fit with the user id less WebAuthn setup.
What's the feeling on using external libraries to make this go faster/smoother?
Specifically:
- elixir2fa (TOTP and HOTP [which would cover recovery codes as well], plus QR codes via Google Charts API)
- passwordless_auth (SMS-based [via Twilio] passwordless or multi-factor auth)
- wax (for FIDO/WebAuthn)
I don't mind using a library to do the heavy lifting at all, but I don't plan to add any more dependencies to Pow so it would have to be an adapter setup, or an extension. No matter how it will be, I believe the biggest hurdle is to refactor the code so it's flexible enough to handle a custom auth flow (independent on what auth logic is used).
An extension is probably sanest, then. Refactoring is certainly quite the task.
Yeah. I've been too busy, but now with API integration guide and out-of-the-box distributed Mnesia released soon, I believe this is probably the next thing I'll take a dig at 😄
Sounds awesome! Looking forward to removing my custom-rolled 2FA stuff in favor of the official implementation. (Fewer things I can do wrong if I'm not the one doing them. :joy: )
For sure. If you can share the code, I would be happy to see how you solved it (maybe gist or repo)!
Still implementing, but an extension that hooks into before_respond/4 is my current plan.
Any updates on how this is going? Would love to see MFA in Pow!