I'm trying to add OTP/2FA support into OAuth2, but after much reading through the RFC6749, it's still not clear how OTP/2FA could be cleanly added without violating the specification.
Although OTP/2FA entry can be added into the authorize
dialog flow, there is no provision for adding it into token
. For example, public
client apps with Resource owner password-based
privileges may want to provide the token directly when requesting a new access_token
, rather than having to embed a HTML dialog box.
Therefore my questions are;
Does the RFC allow for custom grant_type
? Should this be used to provide 2FA/OTP functionality?
Does the RFC allow for additional attributes on an existing grant_type
? For example, grant_type=token&otp_code=1234
(RFC does not make it clear if additional attributes are allowed on grant_type
's within the specification)
Should OTP functionality be placed into headers? This is the approach that Github used, but it feels really ugly/hacky.
Are there any other approaches that I have overlooked?
Thank you in advance
For most cases, we recommend using the Authorization Code Flow with PKCE because the Access Token is not exposed on the client side, and this flow can return Refresh Tokens. To learn more about how this flow works and how to implement it, see Authorization Code Flow with Proof Key for Code Exchange (PKCE).
OAuth2 is for "Server Site Authorization" of certain parameter(s) access (designated by Server site) given to a requesting entity (or App). Whereas 2FA is about Authenticating an Account Owner entity logging into an Account on the Server Site (with full owner access).
OAuth is designed to be a secure alternative for sending authentication data directly from a client to a server. During such process a client can read or store resource owner's credentials. OAuth mitigates the risks of data breaches that come from sharing credentials.
The RFC allows for an extension (custom) grant, see section https://www.rfc-editor.org/rfc/rfc6749#section-8.3. That grant could define additional attributes.
OAuth 2.0 does not define how the Resource Owner authenticates to the Authorization Server, with the exception of the Resource Owner Password Credentials grant. Your proposal could be designed as an extended variant of that grant.
I'm working on something similar. I've got an endpoint at which you can request certain metadata for a user such as whether or not 2fa / mfa / otp is turned on and the salt (and iterations and algorithm) for Proof of Secret / Secure Remote Password.
If you go that route you can simply extend the grant types with an mfa or totp field (that's what I'm doing). You could also create a custom grant type as mentioned above (perhaps more proper).
Another solution is to check for MFA / 2FA / OTP during the authorization dialog step.
If I were done with my OAuth2 implementation I'd link you to that code too, but here are some libraries for an Authenticator:
Browser Authenticator has the components you need to generate and verify a key and token in the browser: https://git.coolaj86.com/coolaj86/browser-authenticator.js
Node Authenticator has the complementary server-side code: https://git.coolaj86.com/coolaj86/node-authenticator.js
You would still need to provide your own database storage mechanism and link it in to your OAuth implementation or you could make a very simple one and run it as a microservice.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With