brockallen / BrockAllen.MembershipReboot

MembershipReboot is a user identity management and authentication library.
Other
742 stars 238 forks source link

Slow login performance #638

Closed jlehew-sd closed 8 years ago

jlehew-sd commented 8 years ago

We're experiencing delays when logging in (using page load time Chrome plugin):

  1. Time to display bad password message after clicking login - 5.56s in dev, 6.7s in Azure
  2. Time to login - 5.43s in dev, 6.45s in Azure
  3. Time to logout - 1.18s dev, 0.67s in Azure Most of the time (3.5 to 4.5 seconds) is spent executing the UserAccountService.AuthenticateWithUsernameOrEmail( {username}, {password}, out {account}) method in BrockAllen.MembershipReboot. Should it take this long? Google Analytics shows were losing customers on our login page.

Our servers are all hosted in Azure, except our dev environment which all runs on my laptop.

Web.config settings

Thanks!

brockallen commented 8 years ago

You need to set the iteration count to a number that feels right for your production scenarios.

jlehew-sd commented 8 years ago

Ok, changed the passwordHashingIterationCount in web.config to 1 (from 0) and the 5.43s time above is now 5.14s. It improved it slightly but needs to run under 1 second if possible.

Our production system is in beta and has less than 5 concurrent users. The times above are for the 2nd login attempt to ensure the web pages, data, etc. are already JIT compiled and in cache.

Any other suggestions?

brockallen commented 8 years ago

Changing that value will only affect new accounts. The existing accounts will use the old iteration count. You will need to write some logic at login time if you want to rehash existing account's passwords.

-Brock

On Apr 22, 2016, at 11:17 AM, jlehew-sd notifications@github.com wrote:

Ok, changed the passwordHashingIterationCount in web.config to 1 (from 0) and the 5.43s time above is now 5.14s. It improved it slightly but needs to run under 1 second if possible.

Our production system is in beta and has less than 5 concurrent users. The times above are for the 2nd login attempt to ensure the web pages, data, etc. are already JIT compiled and in cache.

Any other suggestions?

— You are receiving this because you commented. Reply to this email directly or view it on GitHub

brockallen commented 8 years ago

Also, I forget how the internals of MR work when the account's stored count is different than the current configured count. If it does nothing, then perhaps there's an enhancement here that should re-hash and store with the current configured count.

jlehew-sd commented 8 years ago

I loaded up the source and stepped thru the code...

The slow code is in the VerifyHashedPassword method in the Crypto static class, namespace BrockAllen.MembershipReboot.Helpers.

on the lines 127-130, it has using (var deriveBytes = new Rfc2898DeriveBytes(password, salt, iterationCount)) plus the .GetBytes call in the using statement.

You were correct about the iterationCount as the cause. It was set to 256000 in the Locals window and the .GetBytes call took 3.4 second. Changing iterationCount to 20 reduced it to under <= 1ms.

What's the best way to change the iterationCount as changing in the Web.config didn't affect it? And what is the lowest value iterationCount should be set to? Setting to 10,000 took 170ms.

Thanks! John

brockallen commented 8 years ago

Some reading: https://brockallen.com/2014/02/09/how-membershipreboot-stores-passwords-properly/