Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Registration only with One Time Passcodes #2567

Open
coldlink opened this issue Feb 13, 2024 · 0 comments
Open

Registration only with One Time Passcodes #2567

coldlink opened this issue Feb 13, 2024 · 0 comments

Comments

@coldlink
Copy link
Member

coldlink commented Feb 13, 2024

Why?

We've now upgraded to Okta Identity Engine. This unlocks a number of new features which previously weren't feasible. One of these is "passwordless", or the idea of eliminating, or reducing the need for passwords.

We also currently have an issue within our OAuth flows where users don't always end up signed in the same browser context that they registered from. This can occur if a user clicks a reset password/registration verification link in their on another browser or device, or if deeplinking/https interception isn't working properly on the user's device.

One way of fixing both these issues it to use One Time Passcodes (OTPs), where instead of a user clicking a link in an email, they have to type a 6 digit number into an input field which performs the same action of verifying the user. This means that the user always stays within the same browser device/context, while also securely verifying the user.

To begin with we're going to only implement OTPs for registration only, with the user still having to set a password. After this we will being rolling out full passwordless.

Flowchart

what have i done...

flowchart TD;

start[\User comes to Gateway\] -- Register Page --> register;

register[User enters email address] --> register-interact;

register-interact([POST /oauth2/auth_server/v1/interact]) -- Get interction_handle --> register-introspect;

register-introspect([POST /idp/idx/introspect\ninteractionHandle in body]) -- Get and store stateHandle\nin encryptedState\nunless specified, all calls\nuse stateHandle in body --> register-enroll;

register-enroll([POST /idp/idx/enroll]) -- Error --> register-enroll-error;
register-enroll([POST /idp/idx/enroll]) -- Success --> register-enroll-email;

register-enroll-error{{What error was it?}};
register-enroll-error -- unknown error --> register-enroll-error-unknown;
register-enroll-error -- stateHandle\nexpired--> register-enroll-error-expiry;

register-enroll-error-unknown{{An error case which doesn't match any of the others}} --> okta-classic-registration-fallback;
register-enroll-error-expiry{{User took too long.\nDifficult to get here as\nexpiry of stateHandle is\n2 hours here}} -- restart with email --> register-interact;

register-enroll-email([POST /idp/idx/enroll/new\nuserProfile: email, isGuardianUser,\nregistrationPlatform, registrationLocation]);
register-enroll-email -- Error --> register-enroll-email-error;
register-enroll-email --> register-email-sent;

register-enroll-email-error{{What error was it?}};
register-enroll-email-error -- unknown error --> register-enroll-email-error-unknown;
register-enroll-email-error -- Form\nvalidation error --> register-enroll-email-error-validation;
register-enroll-email-error -- User already exist --> register-enroll-email-error-user-exists;

register-enroll-email-error-unknown{{An error case which doesn't match any of the others}} --> okta-classic-registration-fallback;
register-enroll-email-error-validation{{e.g. missing field, email wrong/invalid}} -- show page with error --> register;
register-enroll-email-error-user-exists{{A user already exists in Okta\nfor the given email.}} -- Send existing\nUser Already Exists\nemail --> okta-classic-registration-fallback;

register-email-sent[Show email sent page\nwith set passcode box];
register-email-sent -- User clicks change email\nclear encryptedState --> register;
register-email-sent -- User clicks resend email --> register-email-sent-resend;
register-email-sent -- User types passcode from email,\nand clicks submit --> register-passwordless;

register-email-sent-resend([POST /idp/idx/challenge/resend]) --> register-email-sent;

register-passwordless([POST /idp/idx/challenge/answer\ncredentials: passcode]);
register-passwordless -- Error --> register-passwordless-error;
register-passwordless -- Success --> register-passwordless-complete-password;

register-passwordless-error{{What error was it?}};
register-passwordless-error -- unkown error --> register-passwordless-error-unknown;
register-passwordless-error -- stateHandle/token\nexpired --> register-passwordless-error-expiry;
register-passwordless-error -- incorrect passcode --> register-passwordless-error-incorrect-passcode;

register-passwordless-error-unknown{{An error case which doesn't\nmatch the others}} -- send user security email\nto set password --> okta-classic-registration-fallback

register-passwordless-error-expiry{{Expired\nafter 30 mins}} -- send user security email\nto set password --> okta-classic-registration-fallback

register-passwordless-error-incorrect-passcode{{Wrong passcode error}}
register-passwordless-error-incorrect-passcode -- display error --> register-email-sent

register-passwordless-complete-password([POST /idp/idx/credential/enroll\nauthenticator: id, factorType=password]);
register-passwordless-complete-password -- Error --> register-passwordless-complete-password-error;
register-passwordless-complete-password -- Show set password page --> register-passwordless-set-password;

register-passwordless-complete-password-error{{What error is it?}}
register-passwordless-complete-password-error -- unknown --> register-passwordless-complete-password-error-unknown
register-passwordless-complete-password-error -- validation --> register-passwordless-complete-password-error-validation

register-passwordless-complete-password-error-unknown -- send user security email\nto set password --> okta-classic-registration-fallback

register-passwordless-complete-password-error-validation{{e.g. weak password, not long, too long etc}} --> register-passwordless-complete-password

register-passwordless-set-password[User enters password];
register-passwordless-set-password --> register-password-set-password-answer;

register-password-set-password-answer([POST /idp/idx/challenge/answer\ncredentials: passcode=password]);
register-password-set-password-answer -- Error --> register-password-set-password-answer-error;
register-password-set-password-answer -- Get and set\nidx cookie\nclear encryptedState --> login-token-redirect;

register-password-set-password-answer-error{{What error was it?}}
register-password-set-password-answer-error -- Unknown error --> register-password-set-password-answer-error-unknown
register-password-set-password-answer-error -- User took too long --> register-password-set-password-answer-error-timeout
register-password-set-password-answer-error -- Validation Error --> register-password-set-password-answer-error-invalid

register-password-set-password-answer-error-unknown -- send user security email\nto set password --> okta-classic-registration-fallback

register-password-set-password-answer-error-unknown{{An error which doesn't match\nthe others}}

register-password-set-password-answer-error-timeout{{stateHandle expired\n30 mins}} -- send user security email\nto set password --> okta-classic-registration-fallback

register-password-set-password-answer-error-invalid{{e.g. password too short, too long, weak etc}}
register-password-set-password-answer-error-invalid --> register-passwordless-set-password

login-token-redirect([303 Redirect to\n/login/token/redirect?stateToken=stateHandle.splitByTilde0]) -- This sets Global SSO session --> complete-oauth-flow;

complete-oauth-flow[/Complete Authorization Code Flow\nThis will redirect user back to app/];

okta-classic-registration-fallback[/Use Okta Classic registration fallback/]
@coldlink coldlink changed the title Registration with One Time Passcodes Registration only with One Time Passcodes Feb 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant