We have customers that have accounts on our platform, but are authenticating through their own SAML Identity Provider (I call this authentication delegation). We don't have any password on our platform for these accounts: we redirect the user to the 3rd party authentication when we detect that the email has an authentication delegation.
The issue is that their users come to our platform through our login page, enter their email, and then enter their corporate password in our password field. The login obviously fails (because we cannot verify their password), and we redirect the user to their corporate authentication page, where they can login. This is a security issue because we have to explain to their users that they shouldn't enter their password because they are leaking it to us... which is complicated to justify.
So what we did (and what twilio, microsoft and google did) is separate the email and password in two steps, so that:
- standard users have 2 steps to login, we can verify their passwords, all is good
- delegated users enter their email, we check how to authenticate them, and redirect them to their own login page
I suspect 90% of the split logins like this are due to that "password isn't needed" issue. Twilio dangles the security check in their article, but in reality this is to accomodate big corporate clients.
Also, don't do it like microsoft: you enter the email, type "TAB" to go to the password, and the page disappears under your nose and goes to the IdP page without any hint at what happened.
However, as you can see, many many people see it as a usability problem. The core issue is selection of action based on the account (not user, the user may have multiple accounts) being of a particular type. This mistake is you are attempting to hide the selection from the user perhaps with the intent of making the process easier / less obtrusive.
From a UX point of view I'd say you need to do the opposite, make the selection obtrusive i.e. clear and obvious to the user. Either in the presentation, by explaining what you are doing, or in the functionality by doing the membership selection client side perhaps with a bloom filter, or presenting "corporate", "individual" tabs so that one starts with the correct interface.
Most people are use to the idea of a work or school account vs a personal account, I think just giving users a short explanation and a choice would be MUCH better then this "clever" auto redirection that doesn't make any sense on the face of it.
Because I have. Users do the wrong thing. Constantly. Every single chance they get. There is no level of education that can fix it. Users don't want to do the right thing, they want it to just work with no thought required.
Every option you present to users is one additional source of support calls, frustrated users, and frustrated account managers wondering why you're making things so hard for the users belonging to customers they work with.
So my company split its authentication page in two also. It results in fewer support calls and fewer complaints to the account managers.
And for what it's worth, it works with most password managers too. Anyone having trouble with that should consider a different option. It's not like there is a shortage.
Normal users would see nothing out of the ordinary, and SAML users would see what they see now plus an optional explanation for what's going on.
I have received my fair share of confused calls regarding (microscopically) more arduous login processes and presenting fewer people with any change at all helps tremendously with reducing those calls.
This might be a factor of having been done just this year. A year back, the decision might have broken the other way.
Add some AJAX to that damn thing. You don't need to pull off a microsoft and redirect without notice. It can be as simple as hiding the password field and showing a button for the 3rd party auth provider instead as soon as the user enters their email. Payment forms have perfected this kind of technology a long time ago; they can rearrange the form to suit the card type as soon as you enter the first few digits of your CC number. There's no reason login needs to be any more clunky.
An AJAX solution can still be the right tradeoff of user experience vs security for some sites, and the article gave a couple of examples of major sites that have followed your suggestion. But the security downsides mean it's not right for every case.
I've thought about doing a client-side challenge token and subtlecrypto to pbkdf2 that to generate a key, then sign the login request with the generated key. I could use a pool of precomputed keys on the server and associate the key source sent via http-only cookie for the key's id in the DB. Unfortunately still have to support the non-chrome edge browser which seems to have some gaps in browser crypto support.
You could rate limit based on IP, or even in the javascript, if you're that concerned -- .onblur sends the request, which typically responds quickly with a "password not needed" flag. You're just trying to stop casual snoopers, as for scripts it's not much different to sending the request as part of the entire form (and seeing if the response is a page or a redirect)
If the number of auth providers are small and tied to specific domains in the email address, perhaps you could speed up the process by pre-loading a hash table of domains => auth providers.
(i.e. replace it with a div saying "you will be redirected to your corporate login page to complete authentication" to avoid the "without any hint" issue)
My federated (AAD) login for msft work things (Azure portal, O365, some VSTS) is <username>@<company>.com.
My non-federated login for other msft work things (down to a couple old VSTS accounts that aren't migrated yet) is <first.last>@<company>.com.
So when I enter my username for non-federated things, it has to ask me whether to forward to AAD or prompt for a password. Because my login ID looks like it should be federated, but doesn't actually exist in their upstream.
I talked to them at Build and the response was basically ‘fuck you passwords are dead’ which I guess is fine except they clearly aren’t. It was particularly infuriating in the context of everyone else doing it right.
Keepassxc auto-type allows you to add a delay between writing the username and writing the password.
Works just fine for me in these "two step" login scenarios.
Edit to clarify:
This is what I am talking about:
https://github.com/keepassxreboot/keepassxc/wiki/Autotype-Cu...
What if the one-page login is changed to require additional information? At least one airline loyalty program I belong to now requires User Id, Last Name, and Password to be filled in.
Credential-collecting workflows have myriad ways to break the "standard" of USERNAME<tab>PASSWORD<return> that are present regardless of how many pages the workflow spans.
Ha! Yes AA’s login field requiring both your name and id is annoying but United takes the cake for asking you “secret questions” on every login and you have to pick the answers from a 10-choice drop down.
I don't know the login process for specific services I use. I don't know what they require or how many pages they are. It takes me less than a minute to configure a login sequence. And it works.
So, to me, none of these login workflows are broken. And the games of "yes, but" that others (not you) are playing is silly, because people are trying to tell me I'll be frustrated doing a thing that has decreased frustration for me for years.
Which of us is happier?
Firefox uses a weaker scheme, but the passwords are still encrypted and it's definitely less accessible for an intruder compared to a plain text file.
In browsers that use the OS' password storage then they will normally be stored in encrypted form, although the browser integration is seamless so you won't notice the difference.
In both cases, there is a significant security advantage in cases where the data on disk is leaked (say, if someone steals your computer and you don't have full-disk encryption.
While typing this on Chrome for iOS, I attempted to fill my password in this text area. Chrome will not let me, and posts an alert informing that the field is insecure.