Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC - Asp.Net Identity. HOWTO log to DB when user logs in

I added a DateTime? LastLoggin property to my AppUser class. I like to set the property to DateTime.Now whenever the user logs in. Logs in using the login view or when automatic loggin in by cookies.

What is the place to actually capture the login ? Any 'best-practices' would be appreciated.

like image 341
BrilBroeder Avatar asked Dec 04 '14 14:12

BrilBroeder


1 Answers

It depends. If you are using identity 2.1, they introduced a new class called SignInManager. This class wraps the OWIN AuthenticationManager class, which is actually responsible for signing the user in. In asp.net 2.1, you would see few sign-in methods within SigninManager such as

  • PasswordSignInAsync()

  • ExternalSignInAsync()

  • SignInAsync() and

  • TwoFactorSignInAsync().

Once the user information is retrieved from the database and the checks are made, all these methods will call AuthenticationManager.Signin() to actually sign the user in. This would have been the perfect place but this is an interface member set by OWIN, so you wont be able to override its Signin method. So the best place to capture a user login would be the SigninManager.SigninAsync(...) method in my humble opinion. This is because if the credentials are valid, and the user is not locket out etc etc, all the methods I mentioned above such as

  • PasswordSignInAsync()
  • ExternalSignInAsync()
  • TwoFactorSignInAsync()

hit SigninManager.SigninAsync(...). Since this method is virtual, you can override in your SigninManager class and do something like this

public override async Task SignInAsync(ApplicationUser user, bool isPersistent, bool rememberBrowser)
    {
        await base.SignInAsync(user, isPersistent, rememberBrowser);
        user.LastLogin= DateTime.Now;
        UserManager.Update(user);
    }

Note that by calling UserManager.Update(), you will hit the database, but I don't see how you can avoid that. asp.net identity methods like to hit the database, and unless you override their implementations, you will have to live with that. (Using SigninManager.PasswordSignin() without any customization to the base classes hits the database 4 times according to my SQL trace)

If you are not using asp.net identity 2.1, the SigninManager class does not exist. (MS had a sample nuget project which had a similar helper class, but it was not part of the framework). You will need to find the method in that helper class and override (or change) the signin method.

As a final note, the documentation for asp.net identity is not super complete in my humble opinion and the source code is not public yet. I used JetBrains DotPeek to look at the code within the Microsoft.AspNet.Identity.Owin assembly and the SigninManager class. The flow I mentioned to you (how every method somehow ends up hitting SigninAsync()) is my interpretation of the code from DotPeek. Feel free to verify and make sure that I didnt miss something. Good luck.

like image 98
freud Avatar answered Nov 14 '22 19:11

freud