I'm trying to understand the proper way to do authentication in ASP.NET Core. I've looked at several Resource (Most of which are out dated).
Simple-Implementation-Of-Microsoft-Identity
Introduction to Authentication with ASP.Core
MSDNs Introduction to Identity
Some people provide altenative solutions stating to use a cloud based solution such as Azure AD, or to Use IdentityServer4 and host my own Token Server.
In Older version Of .Net one of the simpler forms of authentication would be to create an Custom Iprinciple and store additional authentication user data inside.
public interface ICustomPrincipal : System.Security.Principal.IPrincipal { string FirstName { get; set; } string LastName { get; set; } } public class CustomPrincipal : ICustomPrincipal { public IIdentity Identity { get; private set; } public CustomPrincipal(string username) { this.Identity = new GenericIdentity(username); } public bool IsInRole(string role) { return Identity != null && Identity.IsAuthenticated && !string.IsNullOrWhiteSpace(role) && Roles.IsUserInRole(Identity.Name, role); } public string FirstName { get; set; } public string LastName { get; set; } public string FullName { get { return FirstName + " " + LastName; } } } public class CustomPrincipalSerializedModel { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } }
Then you would Serialize your data into a cookie and return it back to the client.
public void CreateAuthenticationTicket(string username) { var authUser = Repository.Find(u => u.Username == username); CustomPrincipalSerializedModel serializeModel = new CustomPrincipalSerializedModel(); serializeModel.FirstName = authUser.FirstName; serializeModel.LastName = authUser.LastName; JavaScriptSerializer serializer = new JavaScriptSerializer(); string userData = serializer.Serialize(serializeModel); FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket( 1,username,DateTime.Now,DateTime.Now.AddHours(8),false,userData); string encTicket = FormsAuthentication.Encrypt(authTicket); HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket); Response.Cookies.Add(faCookie); }
My questions are:
How can I authenticate similar to the way done in previous version's of .Net does the old way still work or is there a newer version.
What are the pros and cons of using your own token server verses creating your own custom principle?
When using a cloud based solution or a separate Token server how would you Integrate that with your current application, would I would still need a users table in my application how would you associate the two?
Being that there are so many different solutions how can I create an enterprise application, to allow Login through Gmail/Facebook while still being able to expand to other SSO's
Why do we need IdentityServer4? ASP.NET Identity can receive a security token from a third-party login provider like Facebook, Google, Microsoft and Twitter. But If you want to issue a security token for a local ASP.NET Identity user you need to work with a third-party library like IdentityServer4, OpenIddict.
IdentityServer is an authentication server that implements OpenID Connect (OIDC) and OAuth 2.0 standards for ASP.NET Core. It's designed to provide a common way to authenticate requests to all of your applications, whether they're web, native, mobile, or API endpoints.
ASP.NET Core Identity is basically a membership system that provides login functionality including user registration in any ASP.NET Core applications. This new authentication system is intended to replace the existing membership system of classic ASP.NET.
TL;DR
IdentityServer = token encryption and validation services via OAuth 2.0/OpenId-Connect
ASP.NET Identity = current Identity Management strategy in ASP.NET
How can I authenticate similar to the way done in previous version's of .Net does the old way still work or is there a newer version.
I see no reason why you couldn't achieve the old way in ASP.NET Core, but in general, that strategy was replaced with ASP.NET Identity, and ASP.NET Identity is alive and well in ASP.NET Core.
https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity
ASP.NET Identity uses a backing store like SQL Server to hold user information like username, password (hashed), email, phone and easily be extended to hold FirstName, LastName or whatever else. So, there really no reason to encrypt user information into a cookie and pass it back and forth from client to server. It supports notions like user claims, user tokens, user roles, and external logins. Here are the entities in ASP.NET Identity:
What are the pros and cons of using your own token server verses creating your own custom principle?
A token server would be a system that generates a simple data structure containing Authorization and/or Authentication information. Authorization usually takes the for of a token named access_token. This would be the "keys to the house", so to speak, letting you through the doorway and into the residence of a protected resource, usually a web api. For Authentication, the id_token
contains a unique identifier for a user/person. While it is common to put such an identifier in the access_token, there is now a dedicated protocol for doing that: OpenID-Connect.
The reason to have your own Security Token Service (STS), would to be to safeguard your information assets, via cryptography, and control which clients (applications) can access those resources. Furthermore, the standards for identity controls now exist in OpenID-Connect specifications. IdentityServer is an example of a OAuth 2.0 Authorization Server combined with an OpenID-Connect Authentication server.
But none of this is necessary if you just want a user table in your application. You don't need a token server- just use ASP.NET Identity. ASP.NET Identity maps your User to a ClaimsIdentity object on the server- no need for a custom IPrincipal class.
When using a cloud based solution or a separate Token server how would you Integrate that with your current application, would I would still need a users table in my application how would you associate the two?
See these tutorials for integrating separate identity solutions with an application: https://identityserver4.readthedocs.io/en/latest/quickstarts/0_overview.html https://auth0.com/docs/quickstart/webapp/aspnet-core
At a minimum you would need a two column table mapping the username to the external provider's user identifier. This is what the AspNetUserLogins table does in ASP.NET Identity. The rows in that table however are dependent on the being a User record in AspNetUsers.
ASP.NET Identity supports external providers like Google, Microsoft, Facebook, any OpenID-Connect provider, Azure AD are already there. (Google and Microsoft have already implemented the OpenID-Connect protocol so you don't need their custom integration packages either, like this one, for example). Also, ADFS is not yet available on ASP.NET Core Identity.
See this doc to get started with external providers in ASP.NET Identity:
https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/
Being that there are so many different solutions how can I create an enterprise application, to allow Login through Gmail/Facebook while still being able to expand to other SSO's
As explained above, ASP.NET Identity already does this. It's fairly easy to create an "External Providers" table and data drive your external login process. So when a new "SSO" comes along, just add a new row with the properties like the provider's url, the client id and secret they give you. ASP.NET Identity already has the UI built in there Visual Studio templates, but see Social Login for cooler buttons.
Summary
If you just need a users table with password sign in capabilities and a user profile, then ASP.NET Identity is perfect. No need to involve external authorities. But, if have many applications needing to access many apis, then an independent authority to secure and validate identity and access tokens makes sense. IdentityServer is a good fit, or see openiddict-core, or Auth0 for a cloud solution.
My apologies is this isn't hitting the mark or if it is too introductory. Please feel free to interact to get to the bulls-eye you are looking for.
Addendum: Cookie Authentication
To do bare bones authentication with cookies, follow these steps. But, to my knowledge a custom claims principal is not supported. To achieve the same effect, utilize the Claims list of the ClaimPrincipal
object.
Create a new ASP.NET Core 1.1 Web Application in Visual Studio 2015/2017 choosing "No Authentication" in the dialog. Then add package:
Microsoft.AspNetCore.Authentication.Cookies
Under the Configure
method in Startup.cs
place this (before app.UseMvc
):
app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationScheme = "MyCookieMiddlewareInstance", LoginPath = new PathString("/Controller/Login/"), AutomaticAuthenticate = true, AutomaticChallenge = true });
Then build a login ui and post the html Form to an Action Method like this:
[HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Login(String username, String password, String returnUrl = null) { ViewData["ReturnUrl"] = returnUrl; if (ModelState.IsValid) { // check user's password hash in database // retrieve user info var claims = new List<Claim> { new Claim(ClaimTypes.Name, username), new Claim("FirstName", "Alice"), new Claim("LastName", "Smith") }; var identity = new ClaimsIdentity(claims, "Password"); var principal = new ClaimsPrincipal(identity); await HttpContext.Authentication.SignInAsync("MyCookieMiddlewareInstance", principal); return RedirectToLocal(returnUrl); } ModelState.AddModelError(String.Empty, "Invalid login attempt."); return View(); }
The HttpContext.User object should have your custom claims and are easily retrievable the List collection of the ClaimPrincipal.
I hope this suffices, as a full Solution/Project seems a bit much for a StackOverflow post.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With