Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Authentication in ASP.Net-Core

I am working on a web app that needs to integrate with an existing user database. I would still like to use the [Authorize] attributes, but I don't want to use the Identity framework. If I did want to use the Identity framework I would add something like this in the startup.cs file:

services.AddIdentity<ApplicationUser, IdentityRole>(options => {     options.Password.RequireNonLetterOrDigit = false; }).AddEntityFrameworkStores<ApplicationDbContext>()   .AddDefaultTokenProviders(); 

I'm assuming I have to add something else there, and then create some kind of class that implements a specific interface? Can somebody point me in the right direction? I'm using RC1 of of asp.net 5 right now.

like image 310
rgvassar Avatar asked Mar 18 '16 22:03

rgvassar


People also ask

How do I authenticate in .NET Core?

In this article. Authentication is the process of determining a user's identity. Authorization is the process of determining whether a user has access to a resource. In ASP.NET Core, authentication is handled by the authentication service, IAuthenticationService, which is used by authentication middleware.

What is custom authentication?

Custom authentication, which includes both username/password tokens and custom tokens, is an integral part of the proxy service definition. When a proxy service is exported, any configuration of custom tokens is included in the jar file.


2 Answers

From what I learned after several days of research, Here is the Guide for ASP .Net Core MVC 2.x Custom User Authentication

In Startup.cs :

Add below lines to ConfigureServices method :

public void ConfigureServices(IServiceCollection services) {  services.AddAuthentication(     CookieAuthenticationDefaults.AuthenticationScheme ).AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,     options =>     {         options.LoginPath = "/Account/Login";         options.LogoutPath = "/Account/Logout";     });      services.AddMvc();      // authentication      services.AddAuthentication(options =>     {        options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;     });      services.AddTransient(         m => new UserManager(             Configuration                 .GetValue<string>(                     DEFAULT_CONNECTIONSTRING //this is a string constant                 )             )         );      services.AddDistributedMemoryCache(); } 

keep in mind that in above code we said that if any unauthenticated user requests an action which is annotated with [Authorize] , they well force redirect to /Account/Login url.

Add below lines to Configure method :

public void Configure(IApplicationBuilder app, IHostingEnvironment env) {     if (env.IsDevelopment())     {         app.UseDeveloperExceptionPage();         app.UseBrowserLink();         app.UseDatabaseErrorPage();     }     else     {         app.UseExceptionHandler(ERROR_URL);     }      app.UseStaticFiles();      app.UseAuthentication();      app.UseMvc(routes =>     {         routes.MapRoute(             name: "default",             template: DEFAULT_ROUTING);     }); } 

Create your UserManager class that will also manage login and logout. it should look like below snippet (note that i'm using dapper):

public class UserManager {     string _connectionString;      public UserManager(string connectionString)     {         _connectionString = connectionString;     }      public async void SignIn(HttpContext httpContext, UserDbModel user, bool isPersistent = false)     {         using (var con = new SqlConnection(_connectionString))         {             var queryString = "sp_user_login";             var dbUserData = con.Query<UserDbModel>(                 queryString,                 new                 {                     UserEmail = user.UserEmail,                     UserPassword = user.UserPassword,                     UserCellphone = user.UserCellphone                 },                 commandType: CommandType.StoredProcedure             ).FirstOrDefault();              ClaimsIdentity identity = new ClaimsIdentity(this.GetUserClaims(dbUserData), CookieAuthenticationDefaults.AuthenticationScheme);             ClaimsPrincipal principal = new ClaimsPrincipal(identity);              await httpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);         }     }      public async void SignOut(HttpContext httpContext)     {         await httpContext.SignOutAsync();     }      private IEnumerable<Claim> GetUserClaims(UserDbModel user)     {         List<Claim> claims = new List<Claim>();          claims.Add(new Claim(ClaimTypes.NameIdentifier, user.Id().ToString()));         claims.Add(new Claim(ClaimTypes.Name, user.UserFirstName));         claims.Add(new Claim(ClaimTypes.Email, user.UserEmail));         claims.AddRange(this.GetUserRoleClaims(user));         return claims;     }      private IEnumerable<Claim> GetUserRoleClaims(UserDbModel user)     {         List<Claim> claims = new List<Claim>();          claims.Add(new Claim(ClaimTypes.NameIdentifier, user.Id().ToString()));         claims.Add(new Claim(ClaimTypes.Role, user.UserPermissionType.ToString()));         return claims;     } } 

Then maybe you have an AccountController which has a Login Action that should look like below :

public class AccountController : Controller {     UserManager _userManager;      public AccountController(UserManager userManager)     {         _userManager = userManager;     }      [HttpPost]     public IActionResult LogIn(LogInViewModel form)     {         if (!ModelState.IsValid)             return View(form);          try         {             //authenticate             var user = new UserDbModel()             {                 UserEmail = form.Email,                 UserCellphone = form.Cellphone,                 UserPassword = form.Password             };             _userManager.SignIn(this.HttpContext, user);              return RedirectToAction("Search", "Home", null);          }          catch (Exception ex)          {             ModelState.AddModelError("summary", ex.Message);             return View(form);          }     } } 

Now you are able to use [Authorize] annotation on any Action or Controller.

Feel free to comment any questions or bug's.

like image 115
AmiNadimi Avatar answered Oct 01 '22 05:10

AmiNadimi


Creating custom authentication in ASP.NET Core can be done in a variety of ways. If you want to build off existing components (but don't want to use identity), checkout the "Security" category of docs on docs.asp.net. https://docs.asp.net/en/latest/security/index.html

Some articles you might find helpful:

Using Cookie Middleware without ASP.NET Identity

Custom Policy-Based Authorization

And of course, if that fails or docs aren't clear enough, the source code is at https://github.com/dotnet/aspnetcore/tree/master/src/Security which includes some samples.

like image 24
natemcmaster Avatar answered Oct 01 '22 05:10

natemcmaster