ASP.NET Core 2: Custom Authentication Part 2

Browser-Cookies.jpgIn Part 1 we asked ASP.NET Core to use Cookie based authentication and to include the authentication engine into the request pipeline. In this next simple example, we’ll log the user in and verify they are logged in. ASP.NET Core has a built-in user system, however in these posts I’m assuming you can’t use that and have to use an external user database or web service.

To keep this as narrowly focused as possible, I am skipping the User Manager features like looking up the user in a database and comparing password hashes. If you need a good UserManager.cs file for ASP.NET Core outside of the built-in one, here’s a good one.

In the HomeController.cs add this function. It’ll handle a complete Login:

[AllowAnonymous]
public async Task<IActionResult> SignIn()
{
 
    //Create a plain C# Class
    //In real-life, get this from a database after verifying the username and password
    MyUser user = new MyUser()
    {
        Id = 1,
        Name = "Fred Fish"
    };
 
    //Add the ID of the user and the name to a collection of Claims
    List<Claim> claims = new List<Claim>
    {
        new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
        new Claim(ClaimTypes.Name, user.Name)
    };
 
    //Create the principal user from the claims
    ClaimsIdentity identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
    ClaimsPrincipal principal = new ClaimsPrincipal(identity);
    AuthenticationProperties authenticationProperties = new AuthenticationProperties() {IsPersistent = false};
 
    //Ask MVC to create the auth cookie and store it
    await this.HttpContext
            .SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, 
             principal, authenticationProperties);
 
 
    //DONE!
    return this.RedirectToAction("Index");
}

Let’s break this down now:

We first need a User class, this can be a plain old C# object. There is no magic here.

public class MyUser
{
    public int Id { getset; }
    public string Name { getset; }
}

Next we need to add information about the user we just made to a collection of Claims. Claims can contain groups or roles or names and ids. Think of it as the bucket of certified security information about a user.

List<Claim> claims = new List<Claim>
{
    new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
    new Claim(ClaimTypes.Name, user.Name)
};

We now wrap up all the claims and info about the user into a Principal:

ClaimsIdentity identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
AuthenticationProperties authenticationProperties = new AuthenticationProperties() { IsPersistent = false };
ClaimsPrincipal principal = new ClaimsPrincipal(identity);

And finally, take the Principal and ask the HttpContext to store it in a cookie:

await this.HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, authenticationProperties);

We are now logged in. To check, in the post-login View, have a look at the User

@if (this.User.Identity.IsAuthenticated)
{
    <b>Authenticated!</b>
} 

Done!

 

Advertisements

ASP.NET Core 2: Custom Authentication Part 1

ASP.NET Core 2 comes with easy to use out-of-the-box authentication. In Visual Studio 2017 you can create fully functioning projects via the File | New menu.

These next few tutorials will focus on doing a custom implementation. Perhaps your organization wishes to authenticate against a customer database, or even a web service. I’ll show you how to implement that all using the beautiful ASP.NET Core 2 authentication infrastructure.

Step 1: Create a new blank project, no authentication

For this tutorial we’ll use “.NET Framework” as we’ll be hosting in IIS

custom auth.png

Step 2: Add the NuGet package Microsoft.AspNetCore.Authentication.Cookies

Step 3: In Startup.cs add Cookie customization for the authentication cookie:

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(options =>
            {
                options.ExpireTimeSpan = TimeSpan.FromDays(7);
                options.LoginPath = "/Account/CustomLogin";
                options.Cookie.Name = "MyAuthCookieName";
            }
        );
 
    services.AddMvc();
}

Step 4: In Startup.cs ‘s Configure method add UseAuthentication()

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseBrowserLink();
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }
 
    app.UseAuthentication();  //IMPORTANT
    app.UseStaticFiles();

 

 

In the cookie customization, you can change many features like the login page from the default “/Account/Login” and the name of the Cookie. The defaults are sensible however.

In Part 2 we’ll add a UserManager class which will handle authentication.

This post is possible based on the excellent work at this site.

ASP.NET Core 2: Adding an Authorization Policy

In ASP.NET Core, an Authorization Policy is simply some code that says “Are you allowed to do something” In this rather contrived example, we’re going to only allow access to a Controller’s Action if a weather service indicates it’s raining. Why not 🙂

Step 1: Create a new solution that has some kind of authentication. Doesn’t matter what kind.

Authentication aspnet core.png

Step 2: Create a new AuthorizationPolicyBuilder extension class so we can add the Policy in our Startup.cs in step 3 next.

public static class WeatherAuthorizationPolicy
{
    public static string Name => "IsRaining";
    public static void Build(AuthorizationPolicyBuilder builder)
    {
        builder.RequireAssertion(context => IsRaining(context.User));
    }
    public static bool IsRaining(ClaimsPrincipal user)
    {
        //Todo access a weather service here.
        //return GetWeatherForUser(user);
        return true;
    }
 }

Step 3: Add the Policy in your Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthorization(options =>
    {
        options.AddPolicy(WeatherAuthorizationPolicy.Name, 
                      WeatherAuthorizationPolicy.Build);
    });

Step 4: Add an Authorize attribute to an Action

[Authorize("IsRaining")]
public IActionResult RainInSpain()
{ 
    return View();
}

That’s it.


BONUS

I would recommend creating a Authorize Attribute so that you don’t have the magic string “IsRaining” all over the place. Excluded for simplicity.

public class AuthorizeIsRaining : AuthorizeAttribute
{
    public AuthorizeIsRaining()
           :base(WeatherAuthorizationPolicy.Name) {}
}

You can also call this policy in code by using an injected IAuthorizationService:

public MyNiceController(IAuthorizationService  authorizationService)
{
    _authorizationService = authorizationService;
}
public async Task CheckRain()
{
    var result = await _authorizationService
                .AuthorizeAsync(User, WeatherAuthorizationPolicy.Name);
     if (result.Succeeded)
        { .... }
}

 

ASP.NET Core 2: LLBL + Entity Framework Core

logo

LLBL is an awesome ORM that’s been around for a long time, is actively worked on, has amazing tech support and produces rock solid code. I don’t own stocks, I just love the tool.

This article assumes you have a little bit of experience with LLBL. We’ll be using a new Database and the Database-first design, but you can change that to what suits you.

I’m skipping certain best practices, like using a repository pattern,  for the sake of simplicity.

Step 1: Create a database with a login and at least 1 table.

FincnaceToo.png

Step 2: Create a New LLBL Project for Entity Framework Core v2 and save it in the ASP.NET Core solution folder. Database first

create llbl.png

Step 3: Using the dialog that appears, connect to your database and choose the table(s) you’d like to add

llbl connect.png

Step 4: Add the Tables as Entities

reverse LLBL.png

Step 5: Press the Generate Code button and then the Edit Selected Task Specifics. Change the Destination root folder to .\LLBL

llbl folder.png

Step 6: Press the Perform Tasks button to generate the LLBL projects. Close LLBL.

Step 7: Open Visual Studio 2017 and the ASP.NET Core project. Add the 2 new projects LLBL just created

Step 8: Add a reference to the LLBL projects to your ASP.NET Core main project

Step 9: Add these NuGet Packages to the LLBL Persistence project:

  1. Microsoft.EntityFrameworkCore
  2. Microsoft.EntityFrameworkCore.Relational

Step 10: To the LLBLPersistence project’s DataContext class add a partial file and add this new constructor so ASP.NET Core can pass options to it.

	public partial class FinanceTooDataContext 
	{
	    public FinanceTooDataContext(DbContextOptions<FinanceTooDataContext> options)
                  :base(options)
	    {}

Step 11: Add the LLBL DataContext options to the ConfigureServices of Startup.cs

public void ConfigureServices(IServiceCollection services)
{
   services.AddDbContext<FinanceTooDataContext>(options => options
      .UseSqlServer(Configuration.GetConnectionString("LLBLConnection")));
 

Step 12: Add LLBLConnection to appsettings.json

{
  "ConnectionStrings": {
    "LLBLConnection""data source=.\\sqlexpress;initial catalog=FinanceToo;User ID=MyUserName;Password=password;persist security info=False;packet size=4096"
  },

Step 13: Access the data context in a controller! Done

public class HomeController : Controller
{
    public HomeController(FinanceTooDataContext context)
    {

ASP.NET Core 2: Using SSMS with Entity Framework Core Identity’s LocalDB

When you create a new ASP.NET Core 2 application and use the Authentication Mode “Individual User Accounts” (see below) a LocalDB database is created automatically.

core with identity'

These files are in c:\users\<you>\aspnet-Identity-<random>.mdf . They are intended for local development.

In Visual Studio 2017 you can access them via the SQL Server Object Explorer.

SQl Server Object

However….

I like to use SSMS much better. Here’s how you can open these .MDF files in SSMS.

Step 1: Run SqlLocalDB.exe info from the Binn folder to get a list of instances

SqlLocalDB

Step 2: Get the Named Pipe info by running SqlLocalDB.exe info MSSQLLocalDB

MSSQLLocalDB

Step 3: Open the Named Pipe in SSMS. That’s in!

SSMS.png

ASP.NET Core 2: Adding Typescript Typings the Easy way

Typings are meta data for javascript objects to help ensure your TypeScript is correctly written. Here’s the easy way to add them to your ASP.NET Core 2 project.

Step 1: Add this Visual Studio 2017 Plugin

PackageInstaller

Step 2: Open or create a ASP.NET Core 2 project. Right Click the project and choose “Quick Install

QuickInstalll

Step 3: Add the Typing Engine from npm. It might take a few minutes. npm will add Typings suppport….

Typings engine

Step 4: Change the kind to Typing then select jQuery (or any other one there)

typing jquery

A new Typing folder is added.

typing folder

Step 5: Drag and drop the index.d.ts file in the root of the Typings folder to the top of your .ts files.

drag typings

That’s it! You now have Typings support in your TypeScript files.

 

ASP.NET Core 2: Simple SASS and Typescript Compiling

There are many ways to set up services to compile and minify Typescript and SASS style sheets. In this article I’ll be showing the simplest way using Visual Studio 2017 out-of-the-box.

Step 1: Setup (just once)

Install these plugins for Visual Studio 2017 by Mads Kristensen (everything he makes is golden):

Step 2: Create a ASP.NET Core 2 new project. Call it what ever you want

FileNewASPNETCORE

Step 3: Now for the Typescript: Add a Typescript file by right clicking the wwwroot/js folder and choosing Add. Select Typescript

Animalts.png

Step 3: Edit the new typescript file, perhaps with something simple like:

var animal = "dog";

 

Step 4: Save the file. You’ll notice a new Javascript file is under it all nicely compiled!

jscompiled

By default all the Typescript magic is done for you. To alter how it’s handled, right-click the project and choose Properties, then Typescript.

Step 5: Adding a Sass file. Right click the wwwroot/css folder. Choose Add and add a new sass stylesheet:

sass

Step 6: Right click the new dogs.sass file and choose Web Compile then Compile. Accept any dialogs that appear. A NuGet package will be added.

rightclicksass

A few things have happened. The dogs.css and dogs.min.css are created. As well in the root is a new compilerconfig.json file is made. Here’s where the magic happens.

Step 7: Right click compilerconfig.json and choose Web Compiler then Enable compile on build

compile sass nuget

Done! SASS files will auto compile when ever you build the project.

Task: Right click each SASS file you add just once and choose Web Compile then Compile.