SignInManager,what it is and how,when to use?
C#.NetAuthenticationasp.net Mvc-5asp.net IdentityC# Problem Overview
I am exploring SignInManager class. But the information given on MSDN is very useless. It only tells what are the methods and properties provided.
What I am looking for is,
- What is SignInManager?
- How to use it?
- And I have my own database that contains credentials related info(username and passwords)
How can I use SignInmanager and how to use it so my custom database is used for authenticating users?
I am using asp.net MVC 5 and Visual Studio 2015. In my sample project I have accounts controller that contains action methods like
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
But I have no idea how to use it, MSDN is completely useless to provide info on this. Any helpful links that explains it in details because I have no idea what SignInManager is and what it's for.
Thanks
C# Solutions
Solution 1 - C#
Disclaimer: I am confused by model used in ASP.NET identity myself and what I say is my understanding of things, that may be inaccurate (I might also be stating obvious things, so I apologize). Also, I was playing with Asp.Net Core's identity recently which is slightly different compared to what was available for Asp.Net 4, so I may mix things up.
Cookies
ASP.NET identity operates with two kinds of cookies: Application cookie and External cookie. Application cookie contains your application's identity and is issued by sign in manager. External cookie contains external authentication provider identity and is issued by authentication middleware (such as FacebookAuthenticationMiddleware
, for example). You use sign in manager to consume the external cookie and issue application cookie instead. If you don't use external authentication you don't deal with external cookies.
Sign in manager
Class declared like this:
public class SignInManager<TUser, TKey> : IDisposable
where TUser : class, IUser<TKey>
where TKey : IEquatable<TKey>
So you may use any class as your user as long as it implements IUser<TKey>
interface. Or use IdentityUser
as your base if you start from scratch, which implements IUser<string>
. In the past I attempted to create an implementation that uses int
as TKey
, but abandoned attempt after spending quite some time trying to make it work and not seeing any progress.
Password sign in
SignInManager.SignInAsync
method issues application cookie for the specified user right away without any checks, so if you implement any custom authentication logic, you might want to use it (default asp.net MVC template uses it after registering user so they don't have to authenticate right after registration).
SignInManager.PasswordSignInAsync
given the user name and password checks their validity and issues application cookie if they are correct.
External sign in
Instead of having the user to create login and password for your site specifically you might want them to use some external web site to authenticate and pass the authentication information to you with OAuth.
Asp.Net Identity has notion of User
and Login
, where User
is... well, user (a person), and Login
is the credential with which User
authenticates. User
might have multiple Login
s.
OAuth flow as seen from Asp.Net web site looks like this (based on the default log in flow generated by VS template):
- You set up external authentication providers (authentication middleware) which you are willing to accept (that likely involves registering on external web site. For example, in order to use Facebook authentication you need to create Facebook app, set up return URL there to point to your web site and configure
FacebookAuthenticationMiddleware
with app ID and app secret Facebook provides you with). - You present unauthenticated user with a choice of external providers you support.
- User picks a provider, the choice is sent to your Asp.Net web application
- Web application issues a
ChallengeResult
containing the name of the provider to be used (this usually happens inAccountController.ExternalLogin
), return URL is set to callAccountController.ExternalLoginCallback
and actual return URL user should end up in is saved for later. - Appropriate middleware catches the
ChallengeResult
object and converts it into HTTP redirect response that causes user's browser to go to third party web site that asks user for credentials. - Third part web site upon successful authentication redirects user back to you web site to the specific URL crafted by the authentication middleware (for Facebook it's
/signin-facebook
IIRC). - Authentication middleware intercepts this call, validates the data passed by third party web site and if everything OK issues the external cookie, and redirects you to whatever was set as return URL at step 4 (which should be
AccountController.ExternalLoginCallback
). - In
AccountController.ExternalLoginCallback
you are expected to consume the external cookie and issue an application cookie instead. That's whatSignInManager.ExternalSignInAsync
does: given the log in information it tries to find user with thatLogin
. If it finds, it issues Application cookie; if it does not, it informs you and you should do what you think is right when you receive unknownLogin
(generally, you create new user at this point. Default implementation from VS template asks for additional info at this point and creates user inAccountController.ExternalLoginConfirmation
). After that user is redirected to actual return URL "saved for later" in step 4.
Custom storage
I've been unsuccessful so far with creating custom storage for Asp.Net Identity. It generally involves implementing your own user manager class descending the UserManager<TUser, TKey>
and storage class implementing bunch of interfaces like IUserStore<TUser, TKey>
, IUserRoleStore<TUser, TKey>
, etc.