Securing an API with JSON Web Tokens (Configuring the API)

To add JWT bearer authentication to an ASP.net Core site, you’ll need to add the JWTBearer middleware to the application. The middleware is found in the Microsoft.AspNetCore.Authentication.JwtBearer namespace, and will allow the service to validate a token, and create a ClaimsPrincipal with the claims in the token. To add the middleware to the service, we’ll start by adding authentication with the options DefaultAuthenticationScheme and DefaultChallengeScheme set to JwtBearerDefaults.AuthenticationScheme. So when the [Authorize] attribute is put on controllers or actions, they will default to use JwtBearer authentication. In the Startup.cs file, there should be a ConfigureServices function that provides you with a IServiceCollection interface to do the configuring.

public void ConfigureServices(IServiceCollection services)
{
     services.AddDbContext<RESTContext>();
     services.AddIdentity<IdentityUser, IdentityRole>()
          .AddEntityFrameworkStores<RESTContext>();

     services.AddAuthentication(options =>
     {
          options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
          options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
     })

...

}

JwtBearer Options

The next service we need to add is the JwtBearer service, which allows configuration with the JwtBearerOptions parameter. Here are a list of several of the options.

  • RequiredHttpsMetadata – JWT bearer tokens should never be passed around without using HTTPS. If someone were to intercept a token, they could use it to impersonate the owner of the token. Always set this option to true.
  • AutomaticAuthenticate – When set to true, it will cause the service to automatically authenticate the user defined in the token.
  • Audience – This value represents the service or resource that will receive the incoming token. Remember that list of registered claims that you can put in the payload of a token? Audience is one of them, and if the value in the token doesn’t match what is placed in this option, the token will be rejected.
  • Authority – The authority option is used to specify the address of the authentication server that issued the token. If you set this option, the middleware will use it to get the public key that is used to validate the token’s signature. It will also verify that the issuer claim found in the token matches this value.
     services.AddAuthentication(options =>
     {
          options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
          options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

     }).AddJwtBearer(options =>
     {
          options.Audience = Configuration["Tokens:Issuer"];
          options.RequireHttpsMetadata = true;  
          
       

Take note that I did not set the Authority option. The code sample is running a web application that issues and authenticates tokens that it creates. It is not reaching out to an authentication server to validate the token’s signature. If you were going to use a third party service to provide authentication, than this option becomes important.

Validation Options

We will also need to set the parameters that are used to validate a token. In ASP.net Core 2, this is done with the TokenValidationParameters object.
These are a list of the relevant options.

  • ValidateIssuer(s) – Do you want to validate the issuer of the token? Generally this gets set to true.
  • ValidIssuer – If you’re going to validate the issuer of the token, this is the value should match the issuer claim in the token.
  • ValidateIssuerSigningKey – Do you want to validate the Issuer’s signing key?
  • IssuerSigningKey – This is the public key used to validate JWT tokens. When you put the key here, it means that the service won’t need access to the token issuing authentication server. It could come from a file, certificate store, or as in the example below a configuration file. BTW don’t use the example below, it’s not your best security option.
     services.AddAuthentication(options =>
     {
          options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
          options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

     }).AddJwtBearer(options =>
     {
          options.Audience = Configuration["Tokens:Issuer"];
          options.RequireHttpsMetadata = true;  
          options.TokenValidationParameters = new TokenValidationParameters
          {
               ValidateIssuerSigningKey = true,
               ValidateIssuer = true,
               ValidIssuer = Configuration["Tokens:Issuer"],
               IssuerSigningKey = new SymetricSecurityKey(Encoding.UTF9.GetBytes(Configuration["Tokens:Key"])),
               ValidateLifetime = true
           };

Now the last thing we need to do here is handle the event that gets fired when authentication has failed.

               ValidateIssuer = true,
               ValidIssuer = Configuration["Tokens:Issuer"],
               IssuerSigningKey = new SymetricSecurityKey(Encoding.UTF9.GetBytes(Configuration["Tokens:Key"])),
               ValidateLifetime = true
           };
          options.Events = new JwtBearerEvents()
          {
               OnAuthenticationFailed = c =>
               {
                    c.NoResult();
                    c.Response.StatusCode = 500;
                    c.Response.ContentType = "text/plain";
                    return c.Response.WriteAsync("An error occurred processing your authentication.");
               }
          };

Applying the Attributes

Once the middleware is configured and added to the pipeline, you can use standard authorize attributes on your controllers.
You could also specify that a controller or action use JwtBearer authentication as part of the attribute if you need to be specific.

[Authorize(AuthenticationSchemess = JwtBearerDefaults.AuthenticationScheme)]

Securing an API with JSON Web Tokens (How Do I Create a JWT?)

The typical scenario for creating a JWT would be to have an action in a controller that authenticates a user and returns a token. That token could then be used to authenticate the user for other actions. We’re going to need the help of some classes built into the framework.

using System;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using System.IdentityModel.Tokens.Jwt;

using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;

Several classes need to be initialized via dependency injection, so here is the constructor for the controller.

public AuthController(SignInManager<IdentityUser> signInManager,
                      UserManager<IdentityUser> userManager,
                      IPasswordHasher<IdentityUser> hasher,
                      IConfiguration configuration,
                      ILogger<AuthController> logger)
{
     _signInManager = signInManager;
     _userManager = userManager;
     _hasher = hasher;
     _configuration = configuration;
     _logger = logger;
}

With the groundwork set, let’s look at the function, that will create the JWT.

[ValidateModel]
[HttpPost]
public async Task<IActionResult> CreateToken([FromBody] CredentialModel model)
{
}

The action takes in a CredentialModel, which is just a class with two string properties (Username and Password). Both the properties are annotated with the [Required] attribute. The CreateToken action is decorated with the [ValidateModel], so the model can be checked for a valid model at the beginning of the function. If the model is not valid, we’ll just log it to the informational log, and return a bad request.

if(!ModelState.IsValid)
{
     _logger.LogInformation($"Invalid CredentialModel passed to CreateToken (UserName:{model.UserName} Password:{model.Password}");
     return BadRequest("Failed to create token.");
}

The next step is to authenticate the user with the UserManager from Microsoft.AspNetCore.Identity. One option would be to use an instance of SignInManager, and call the PasswordSignInAsync function. This function will check the user credentials, and create an authentication cookie. If you don’t want the cookie to be created, you can use the IPasswordHasher interface to verify the authentication credentials.

try
{
     var user = await _userManager.FindByNameAsync(model.UserName);

     if(user != null)
     {
          if (_hasher.VerifyHashedPassword(user, user.PasswordHash, model.Password) == PasswordVerificationResult.Success)
          {
               //Create Token
          }
     }
}
catch (Exception ex)
{
     _logger.LogError($"Exception thrown while creating JWT: {ex}");
}

Creating the token

Now let’s work on creating the token.

var userClaims = await = _userManager.GetClaimsAsync(user);

var claims = new[]
{
     new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
     new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
     new Claim(JwtRegisteredClaimNames.Email, user.Email)
}.Union(userClaims);

var key = new SymetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Tokens:Key"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

var token = new JwtSecurityToken(
     issuer: _configuration["Tokens:Issuer"],
     audience: _configuration["Tokens:Audience"],
     claims: claims,
     expires: DateTime.UtcNow.AddMinutes(15),
     signingCredentials: creds);

return Ok(new 
{
     token = new JwtSecurityTokenHandler().WriteToken(token),
     expiration = token.ValidTo
});

Remember that the payload of the JWT is made up of claims, so the first step is to build up a set of claims for the user. The UserManager will return an array of claims, and we can merge those with some commonly used Registered Claims. For example, Jti is the JWT ID claim that provides a unique identifier to prevent replay attacks.

The next step is to create a key and signing credentials. The key is created based on a string found in the config file. Getting this from a key store, or some other method is a MUCH better idea.

Microsoft uses the JwtSecurityToken class to represent JWTs. The constructor takes the elements of a JWT that were mentioned in part 1. Once we have the token, we can return it from the function.

In the last part of this series, I’ll tell you how you can consume the JWT as part of a REST service.

Securing an API with JSON Web Tokens (What is a JWT)?

JSON Web Token, prounced “jot”, is an open standard that lets you securely transmit information as a JSON object. The token can be signed with a secret using HMAC or a public/private key using RSA. This makes JWTs a great option for authentication. Each JWT is comprised of three parts separated by dots, which are the header, payload, and signature.

Here is an example of a JWT.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.
TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

Header

The header defines what kind of token it is, and the type of hashing algorithm that was used to create the token.

{
“alg”: “HS256”,
“typ”: “JWT”
}

The header is Base64URL encoded, which then becomes the first third of the JWT.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

Payload

The second part of the token is the payload, and contains claims and any other metadata about the user. In the example below, claims are included in the payload and then encrypted to create the payload.

{
“sub”: “1234567890”,
“name”: “John Doe”,
“admin”: true
}

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

The claims used in the payload are categorized into three groups.

Registered Claims are predefined claims that are defined in RFC 7519. An application should define which claims it uses, and when they are required or optional. The names of the claims are short, three letters, to keep the size of the token small.

  • “iss” : Issuer Claim – identifies the principal that issued the JWT.
  • “sub” : Subject Claim – identifies the principal that is the subject of the JWT.
  • “aud” : Audience Claim – identifies the recipients that the JWT is intended for.
  • “exp” : Expiration Time – identifies the expiration time on or after which the JWT must not be accepted.
  • “jti” : JWT ID Claim – provides a unique identifier for the JWT. The value can be used to prevent the JWT from being replayed.

Public Claims are defined by who ever is creating the token. The concern here is to choose a name that is not likely to collide with another claim name. Ideally, they should be registered in the IANA “JSON Web Token Claims” registry.

Private Claims are agreed to be used by the who ever produced the token, and those who consume the token. The names are not registered, and are likely to be subject to collisions.

Signature

The purpose of the signature is to verify that the sender is who they say they are, and to ensure that the token was not altered in transmission. The signature is created by combining the encoded header, the encoded payload, and a secret. The information is then encrypted.

How Are JWTs Used To Authenticate Users

Traditionally when a user logs into a server, the service will create a session in the server, and return a cookie. JWTs work a bit differently, because when the service authenticates a consumer, it will create the JWT and return it to the consumer, where it is stored locally. On subsequent calls to the service, the consumer includes the JWT in the Authorization header using the Bearer schema.

Authorization: Bearer

There are multiple benefits to this method. The authentication method is stateless, because there is no need to maintain a session on the server. Furthermore, the JWTs are self-contained, and don’t require additional calls to a database to validate the credentials. If you have a service that makes calls to other APIs, you can simple pass the JWT along. There is no restriction on what domain is serving the API, so CORS, Cross-Origin Resource Sharing, is not an issue.

Static Initializers vs. Static Constructors

Static types generally have static member variables that need to be initialized before an instance of the type can be used. There are a couple of common ways to do that. A static constructor can initialize those variables before they are accessed. They are a good option when you need to have logic built into the initialization process. Static initializers are useful when you only have to allocate the static member.

        private static readonly WeatherMan _instance = new WeatherMan();
        static WeatherMan()
        {
            _instance = new WeatherMan();
        }

If there is a reasonable chance that initializing a member variable could result in an exception, you may want to consider using a static constructor. You can’t catch an exception from a static initializer, with a static constructor you can. If an exception occurs in a static constructor, your program will terminate with an exception. If the caller of the static constructor tries to catch the exception, future attempts to create an instance of the type will fail until the AppDomain is unloaded. Ouch. So the only real option is to catch the exception in the static constructor, and add some recovery logic.

ASP.Net Core Claims Authorization

What are claims?
One of the significant changes to .NET Core is how user’s identity is modeled. In the past, .NET used the IPrincipal interface to access who the current user of an application was. Microsoft is moving to a Claims based model, which should help solve the problems developers are currently facing.

At the heart of the matter, a claim is a key-value pair that tells something about the user. ASP.NET Core uses claims as a way to model identity information. Those claims could come from any number of sources, such as an identity server, database, or even local storage. A claim doesn’t describe what a user can do. It tells something about who the user is. Each claim consists of two string properties, a Type and a Value. Generally the Type property will be populated with constants from the ClaimsType class. It’s also important to know who is providing the claim, so an Issuer can be included in the constructor.

const string Issuer = "https://fansgatherhere.com";
var claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.Name, "Jeff", ClaimValueTypes.String, Issuer));

What is the difference between a ClaimsIdentity and a ClaimsPrincipal?
In many ways, a ClaimsIdentity is like a passport. A passport can have information such as name, height, age, and a photo. Each piece of information is analogous to a claim. To create a new identity, we need to provide the constructor with an authentication type, then add the list of claims. The authentication type is just a string to remind you of what is required for the used to prove their identity.

var userIdentity = new ClaimsIdentity("SuperSecureLogin");
       userIdentity.AddClaims(claims)

With the ClaimsIdentity created, we can move on to the ClaimsPrincipal.

var userPrincipal = new ClaimsPrincipal(userIdentity);

When you examine the properties of the ClaimsPrincipal, you’ll find that there is a collection of ClaimsIdentity objects associated with it. Just like a person can have driver’s license and a passport, a user can have multiple ways identifying themselves. Those identities could come from Twitter, Facebook, Microsoft, or your own store.

Using Claims In Controllers:
Using claims in ASP.NET Core should feel very familiar to working with Authorization in classic ASP.NET. I’ll begin by adding a claim to the ClaimsPrincipal, which I’ll call BackStagePass.

claims.Add(new Claim(ClaimTypes.UserData, "BackStagePass"));

Normally this is something that you would get from a service, or your own data store, but for this example, I’ll just create it in code. Now that I know that the user has the claim, I need to add it to the Authorization service. In the Startup.cs file, I’ll add the Authorization service with a “PassHolders” policy that requires that the user has a “BackStagePass”.

services.AddAuthorization(options =>
       {
                options.AddPolicy("PassHolders", policy => policy.RequireClaim(ClaimTypes.UserData, "BackStagePass"));
        });

Once the policy is added to the authorization service, it can be used in declarative authorization checks. Those checks specify which claims the user must possess, and can require the values that those claims hold.

    [Authorize(Policy = "PassHolders")]
    public class DressingRoomController : Controller

In this example, accessing the controller’s actions will require that the user have a “BackStagePass” claim.

Entity Framework Core – Creating Schemas With the FluentAPI


What’s the difference between storing data in Excel and SQL Server? Schema.

A good schema can help maintain the integrity of your data, and improve the performance of your application.  Entity Framework makes it so easy to create a new database, that it’s easy to forget what’s going on under the hood.  I’ll present some techniques to make EF create databases with indexes, foreign keys, constraints, and inheritance using the Fluent API.

Entity Framework has three methods to create a database schema.  The default method is “convention”.  It uses built in rules based on the name of properties, and entity composition to create the schema.  It’s the method most people use to get started, but you don’t have any control over them.  Another way to configure the schema is to use annotations on the entity model to dictate how the schema is created.  The last and most powerful, is to use the Fluent API.  Configuration options you make using the Fluent API override annotations and conventions. Below is a common data model that I’ll use in my examples.

Identities and Constraints

EF will make the best choice it can when configuring the schema.  For example, if the primary key is an integer, it will make the column an identity column by default.  For every row that is added, the PK is set to the next highest integer in the column.  If you wanted to be explicit about this option, you could do that by overriding the OnModelCreating method of the DbContext object.

public class CRMContext : DbContext

{

     public DbSet<Address> Addresses {get; set;}

     public DbSet<Party> Party {get; set;}

     public DbSet<Person> People {get; set;}

     public DbSet<Organization> Organizations {get; set;}


     protected override void OnModelCreating(ModelBuilder modelBuilder)

     {

          modelBuilder.Entity<Party>()

           .Property(p => p.PartyID

           .UseSqlServerIdentityColumn();

     }
}

Another convention that EF uses, is to create NVARCHAR(MAX) columns to store string data.  It’s a safe guess because it’s flexible in the absence of knowledge about what kind of data will be stored.  If you know that a column will be storing the names of people, you could specify the maximum length the column will store, and improve performance.

modelBuilder.Entity<Party>()

.Property(p => p.DisplayName)

.HasMaxLength(128);

Foreign Keys

In this example, a person or organization inherits from a party.  Each has a collection of addresses that can be associated with them.  This relationship is defined by creating a foreign key property on the database schema.  Using the Fluent API, we begin by declaring the navigation properties of the relationship.  This can be defined as “HasOne” or “HasMany”, depending on the carnality of the relationship.  The inverse navigation can be chained to the definition by using “WithOne” or “WithMany”.

 

protected override void OnModelCreating(ModelBuilder modelBuilder)

{

     modelBuilder.Entity<Party>()

       .HasMany(p => p.Addresses)

       .WithOne(p => p.Party)

       .HasForeignKey(p => p.PartyID)

       .IsRequired()

       .OnDelete(DeleteBehavior.Cascade);

}

After establishing the relationship and its carnality, we need to tell Entity Framework what the foreign key field is.  This is done using HasForeignKey().  It doesn’t make sense to have an address that is not attached to a person or organization, so the foreign key should be required.  This is done with the IsRequired() method.  Because an address is tied to a party, when a party is deleted, we want the related addresses to be deleted as well.  Cascading deletes in SQL Server can handle this problem for us, so we’ll apply that behavior with the OnDelete method.

Indexes

The next step is to create some indexes on the entities to improve performance.  The HasIndex method is used to create an index based on one or more columns.  By default the indexes do not require that each “row” be unique.  That can be configured by using IsUnique.

protected override void OnModelCreating(ModelBuilder modelBuilder)

{

modelBuilder.Entity<Party>()

.HasIndex(p => new { p.PartyID, p.DisplayName })

.IsUnique();

}

Inheritance

Inheritance in a database can take on two distince flavors.  The table-per-hierarchy (TPH) pattern uses a single table to store all the data for all the types in the hierarchy.  The table-per-type (TPT) pattern creates a table for each type in the hierarchy.  Entity Framework currently only supports TPH.  Because data for multiple types will be stored in the same table, an additional piece of information is needed to identify a row’s type.  In EF, this column is called the discriminator.  It can be added to the schema with the HasDiscriminator method.  The values that can be placed in column are defined with the HasValue method.

protected override void OnModelCreating(ModelBuilder modelBuilder)

{

modelBuilder.Entity<Party>()

.HasDiscriminator<string>("PartyType")

.HasValue<Person>("Person")

.HasValue<Organization>("Organization");

}

Because EF is using TPH, the Person DbSet and the Organization DbSet are merged into a Party table. This does limit our ability to use SQL constraints to enforce data integerity. For example, if we need to record the schools that a person has attended, there will be no foreign key constraint that can limit this to people. To prevent an organization from attending a school, we would need to create a insert and update trigger on the School table. TPT modeling would let us avoid having to use a trigger. At this point EF doesn’t support TPT modeling, but it is on Microsoft’s roadmap.  Another thing to take note of is that the extensions needed to set the discriminator are in the Microsoft.EntityFrameworkCore.Relational package in NuGet.

What do you do when you run DBCC CHECKDB and you find corruption?

Data in SQL databases will become corrupted, eventually. Thankfully there are several mechanisms in SQL Server to protect against it, and warn you that there is a problem. One of the most difficult things to learn about, to train for, is database corruption. Most of us don’t have a set of corrupted databases that we can practice repairing. Learning how to repair them in the heat of the moment is stressful, and often poor decisions can be made. With that in mind, I’ve created some tutorials along with corrupted databases for you to practice on. Download the Northwnd.mdf and Northwnd.ldf, attach them to a SQL Server, and run DBCC CHECKDB on the database. You will see an error message that looks like this.
DBCC results for ‘NORTHWND’.
Msg 8939, Level 16, State 98, Line 1
Table error: Object ID 0, index ID -1, partition ID 0, alloc unit ID 1056009275703296 (type Unknown), page (32993:-2015636120). Test (IS_OFF (BUF_IOERR, pBUF->bstat)) failed. Values are 133129 and -1.

Msg 8928, Level 16, State 1, Line 1
Object ID 2137058649, index ID 3, partition ID 984479205752832, alloc unit ID 984479205752832 (type In-row data): Page (1:295) could not be processed. See other errors for details.

Msg 8980, Level 16, State 1, Line 1
Table error: Object ID 2137058649, index ID 3, partition ID 984479205752832, alloc unit ID 984479205752832 (type In-row data). Index node page (0:0), slot 0 refers to child page (1:295) and previous child (0:0), but they were not encountered.

CHECKDB found 0 allocation errors and 2 consistency errors in table ‘Suppliers’ (object ID 2137058649).
CHECKDB found 0 allocation errors and 3 consistency errors in database ‘NORTHWND’.
repair_allow_data_loss is the minimum repair level for the errors found by DBCC CHECKDB (NORTHWND).

At first glance, this looks like a horrible error message. You might be tempted to try recovering the database from a backup, or running DBCC CHECKDB(NORTHWND, REPAIR_REBUILD). But it wouldn’t be necessary in this case. The key to understanding how to solve database corruption problems is to understand what corruption is, and what the error messages are telling you.

What is corruption?
Database corruption is simply a sequence of ones and zeros that got written to a datafile where they should not have been. Sometimes this happens when a hard disk fails to physically perform as it should, a device driver encounters a bug, or some part of the IO subsystem faults. It doesn’t happen often, but when it does, the result can be a huge headache.

The Error Messages:
Let’s look at each of the error messages, and figure out what they mean.
Msg 8939 & 8928 – The job of physically reading the data, is done by the buffer pool. When a page of data is read by the buffer pool, the page’s checksum is checked. If it doesn’t match the computed value of the data, an error is thrown. CHCEKDB is telling us there is corruption, and look at the other error messages to see how to deal with it.
Msg 8980 – This message is telling us that there is an error in object ID 2137058649. I can take a look at sys.indexes to see what that object is.

SELECT object_id, name, index_id, type, type_description FROM sys.indexes WHERE object_id = 2137958649
object_id name index_id type
———– —————————– ———– —-
2137058649 PK_Suppliers 1 1
2137058649 CompanyName 2 2
2137058649 PostalCode 3 2

(3 row(s) affected)

So now we know that the problem lies in the PostalCode index for the Suppliers table. Lets run a query to verify this.

SELECT PostalCode FROM Suppliers
Msg 824, Level 24, State 2, Line 19
SQL Server detected a logical consistency-based I/O error: torn page (expected signature: 0x00000000; actual signature: 0x55555554). It occurred during a read of page (1:295) in database ID 5 at offset 0x0000000024e000 in file ‘C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\NORTHWND.MDF’. Additional messages in the SQL Server error log or system event log may provide more detail. This is a severe error condition that threatens database integrity and must be corrected immediately. Complete a full database consistency check (DBCC CHECKDB). This error can be caused by many factors; for more information, see SQL Server Books Online.

Note that the torn page error message refers to page (1:295). This matches the error we saw in DBCC CHECKDB. Lets see what happens if we try to query the Suppliers table without using the PostalCode index.

SELECT * FROM Suppliers

No error messages are returned. Indexes are really just metadata, so rather than taking a drastic step like recovering from backup, we can just recreate the index.

DROP INDEX [PostalCode] ON [dbo].[Suppliers]
GO

CREATE NONCLUSTERED INDEX [PostalCode] ON [dbo].[Suppliers]
(
[PostalCode] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

After it completes, we can try querying the Suppliers table using the index.

SELECT PostalCode FROM Suppliers

You should now see a list of the postal codes from the table. Now lets run DBCC CHECKDB to see how it looks.

CHECKDB found 0 allocation errors and 0 consistency errors in database ‘NORTHWND’.

The purpose of this exercise is to remind you that corrupted databases will occur, but the first step to solving the problem is to understand what is corrupted.

Northwnd.mdf
Northwnd.ldf

ASP.net MVC Core Routing

Routing in ASP.net MVC solves the problem of mapping a request to a route handler that can return a file, web page, or data. Out of the box, configuring routing is straightforward, but as an application becomes more complex, routing can be challenging. Knowing how routing works, and how to use the different types of routes will help you solve the problems that can arise.

What exactly are routes?

Routes define how requests are should be handled in your application. Each route has three parts that you must configure for them to work.

• Name – Identifies the route.
• Template – A pattern that is used to match to URLs.
• Target – A handler to specify where the request should go.

There are two different ways to define a route with these pieces of information. With conventional routing, you generally establish a standard pattern for mapping a URL to actions in controllers.

Routes.MapRoute(“Default”,
                “{controller}/{action}/{id}”,
                New { controller = “Home”, action = “Index”, id = “” });

In this example, the route is named “Default”, the template is a pattern of the controller name, followed by the action method in the controller, and a variable being passed into the method. Defining a pattern like this allows you to add more controllers and actions to your application, without having to map a URL each time.
Routes can also be defined using the [Route] attribute. You can simply decorate a controller action with the attribute.

[Route(“products/{id}”)]
public IActionResult ProductDetail(int id) { … }

In this case, the name is going to be generated for us, the template will be “products” followed by a variable, and the target will be the action that is decorated. If you are unfamiliar with routing, the “{controller}” or “{id}” might throw you. It is a segment, or parameter, that represents a piece of data that will be parsed from the URL.

How do the requests get applied to the routes?
Each application has a collection of routes. When an incoming request needs to be matched with a route handler, the RouteAsync() method is sequentially called on each route handler in the collection. If the route sets the handler for the request, iteration through the collection is stopped, and the handler is invoked. If a handler is not found, it is passed on the next piece of middleware in the request pipeline. But that’s a story for another day.

Now let’s take a look at some interesting cases.
Let’s say we wanted to have a controller that could display a product when you gave the website the name of the product, or an id number.

GetProductByID(int id) // product/4
GetProductByName(string name) //product/silly-puddy

In this case, we need to see what type of data is being included in the URL. If it is an integer, we want the GetProductByID action to be invoked. If it is a string, we want the GetProductByName action to be invoked. One way to do that is to use a constrained route parameter.

[Route(“product/{productid:int}”)]
public IActionResult GetProductByID(int id)

[Route(“product/{name:string}”)]
public IActionResult GetProductByName(string name)

Microsoft has created several types of route constraints that can be used to evaluate parameters in a URL. A route constraint matcher will iterate through the list of constraints, and call a match function to see if a given URL should be handled by the route. Constraints that check for integers and strings are commonly used, as well as regular expressions for more complex requirements. If you want to see all the available constraints, check out the GitHub repo for ASP.NET.
https://github.com/aspnet/Routing/tree/dev/src/Microsoft.AspNetCore.Routing/Constraints

Sometimes you need a handler for URLs with many segments. One example you need a specific style of webpage for widgets with special features.

[Route(“product/widgets/{*feature}”)]
public IActionResult GetSpecialWidget(string feature)

A wild card parameter will act as a “catch-all” for URLs that may contain multiple segments.
/product/widgets/jumbo/green
/product/widgets/tiny
/product/widget/blue

The wild card parameter can be constrained in the same way normal parameters are.

[Route(“product/widgets/{*feature:string}")]

 

Don’t forget about order!

Remember back when I mentioned that for each application, there is a collection of routes that are checked one by one, until a matching route is found. That means that the order of the routes in the collection matters. If a route with a wildcard parameter was first in the collection, it could swallow up requests that were intended for different handlers. In ASP.net there is a TreeRouteBuilder that is responsible for putting the routes in order. Here is the order by route type.

1) Literal Routes /product/brand-new
2) Constrained Routes with Parameters /product/{productid:int}
3) Unconstrained Routes with Parameters /product/{productname}
4) Constrained Routes with Wildcards /product/{*widgetsize:int}
5) Unconstrained Routes with Wildcards /product/{*feature}

In the event you need to have a route placed higher in the list, you can add an Order parameter to the route definition. All routes have an Order with a default value of zero. Setting the route’s order to a value less than zero will cause it to be checked before those set to zero. Setting the value to 1 will push the route to the end of the collection, and thus be checked later in the matching process.

[Route(“product”, Order=1)]

Hope this helps shed some light on how routing works, and the ways you can use routing features to better control your web applications.

Using the Null Conditional Operator

Using events in C# are pretty straight forward, but there has been a subtle problem that is often overlooked. A multicast delegate object is responsible for invoking all the attached handlers to an event. If there are no attached handlers, when the event is fired, a NullReferenceException will occur. The good news is that a new C# 6.0 feature makes solving this problem much simpler than previous options.
Take a look at a simple example of this problem.

    public class CableNews
    {
        public event EventHandler<string> newsReported;

        public void ReportNewsFlash(string news)
        {
            // Checking to see if the event handler is null before invoking it,
            // will solve the problem most of the time.
            if (newsReported != null)
            {
                newsReported(this, news);
            }
        }
    }

In cases where there are no attached handlers, the event will be null. When you work with a single threaded application, this quick check will solve the problem by not raising the event when no one is listening. Unfortunately, if multiple threads are involved, the listeners could unsubscribe between when the event is checked for null and when the event is invoked. There is a couple way to get around this prior to C# 6.0. Delegates are immutable, so you could create a temporary variable that held a reference to the event, and check the temporary variable to see if it’s null. The compiler could optimize away the temporary variable, so a call to Volatile.Read can be used to avoid that problem.

        EventHandler<string> temp = System.Threading.Volatile.Read(ref newsReported);
        if (temp != null) temp(this, news);

It works, it’s just kind of cumbersome. C# 6.0 introduces the NullConditionalOperator (“?.”) It evaluates the left-hand side of the operator to see if it is null. The expression on the right-hand side is executed when it is not null. Here’s an example of how to apply it to the eventing problem.

newsReported?.Invoke(this, news);

The Invoke method must be used because the compiler doesn’t allow a parentheses to follow the ?. Still, I think this is a much cleaner solution!

Using a Content Security Policy (CSP) To Prevent Cross Site Scripting Vulnerabilities.

Last week while attending IT/Dev Connections, I had the opportunity to sit in a session on web security with Christian Wenz. He focused on the use of Content Security Policy headers to prevent cross site scripting vulnerabilities. It’s a great concept for an additional layer of security to defend your site. A CSP header controls where a web browser is allowed to load content from and the type of content it is allowed to load. This means you can limit the browser to loading css, javascript or images from your own domain, and block other data, such as a malicious script. There are a few gotchas to consider, which I’ll mention a bit later.

The first step in using a CSP is specifying the policy. It’s really a string that contains a list of policy directives to describe how certain resources should be handled. It could look something like this.

Content-Security-Policy: default-src ‘self’

In this case, the “default-src” is the fallback policy for a resource type that doesn’t have a policy specified. The “self” specifies that allowed content will come from the site’s own origin. If you wanted to allow content from subdomains, they could be added to the directive.

Content-Security-Policy: default-src ‘self’ *.mydomain.com

Multiple directives can be included so you can specify how different content types should be handled. Semicolons are used to delimit the directives. So if you wanted to require that all images be loaded from myCDN.com, you could include a directive for images.

Content-Security-Policy: default-src ‘self’ *.mydomain.com; img-src myCDN.com

Another neat trick is to force all content to be loaded using SSL. Simply include the https:// to the directive.

Content-Security-Policy: default-src https://mydomain.com

So here is the first gotcha…Not all browsers support CSP, but most modern browsers do, and it’s getting better! Remember CSP is part of a layered defense, so don’t rely solely on it.

The next step is to create a MVC filter for the CSP. Filters can be applied globally, on an individual controller, or at the action level.

public class ContentSecurityPolicyFilterAttribute : ActionFilterAttribute
{
     public override void OnActionExecuting(ActionExecutingContext context)
     {
          var response = context.HttpContext.Response;
          response.Headers.Add("Content-Security-Policy",
                               "script-src 'self'; style-src 'self';");
          base.OnActionExecuting(context);
     }
}

[ContentSecurityPolicyFilter]
public IActionResult Index()
{
     return View();
}

Once you have an MVC filter in place, you can begin experimenting with CSP. There are a few ways a “default” policy will affect your website. Inline styles will not be applied. Markup such as this will be rendered in the default color, because the inline style will be blocked by default.

<div class="row">
     <div class="btn btn-default" style="color: red;">In line style test.</div>
</div>

Inline scripts are also blocked by default, so you need to make sure all your javascript is loaded from external files.

<div class="row">
     <div class="btn btn-warning">Mouse over attack.</div>
</div>

In this case, with the CSP in place, the inline javascript will not execute when you move the mouse over the button.

If you don’t like the idea of writing the MVC filters, you could install the NWebsec.MVC NuGet package. It provides a collection of MVC filters for each CSP directive, so you can apply them to controller actions as needed. It currently works for ASP.Net MVC 3/4/5 apps. A new version for ASP.Net Core is in the works.