How To Route Constraints In ASP.NET Core

How To Route Constraints In ASP.NET Core

logo

CheapASPNETHostingReview.com | Best and cheap ASP.NET Core. Route Constraints can be a handy way to distinguish between similar route names, and in some cases, pre-filter out “junk” requests from actually hitting your actions and taking up resources. A route constraint can be as simple as enforcing that an ID that you expect in a URL is an integer, or as complicated as regex matching on strings.

An important thing to remember is that route constraints are not a way to “validate” input. Any server side validation you wish to occur should still happen regardless of any route constraints set up. Importantly, know that if a route constraint is not met than a 404 is returned, rather than a 400 bad request you would typically expect to see from a validation failure.

Type Constraints

Type constraints are a simple way to ensure that a parameter can be cast to a certain value type. Consider the following code :

At first glance you might assume that if you called “/api/controller/abc” that the route would not match – It would make sense since the id parameter is an integer. But infact what happens is that the route is matched and the id is bound as 0. This is where route constraints come in. Consider the following :

Now if the id in the URL is not able to be cast to an integer, the route is not matched.

You can do this type of constraints with int, float, decimal, double, long, guid, bool and datetime.

Size Constraints

There are two types of “size” constraints you can use in routes. The first is to do with strings and means you can set a minimum length, max length or even a range.

This sets a minimum length for the string value. You can also use maxlength to limit the length.

Alternatively, you can set how many characters a string can be within a range using the length property.

While that’s great for string variables, for integers you can use the min/max/range constraints in a similar fashion.

Regex Constraints

Regex constraints are a great way to limit a string input. By now most should know exactly what regex is so there isn’t much point doing a deep dive on how to format your regex, just throw it in as a constraint and away it goes.

It is worth noting there for whatever reason, the .NET core team added another handy “quick” way of doing alpha characters only instead of regex. There you can just use the constraint of “alpha”.

Claim Based Security on ASP.NET Core 1.0

Claim Based Security on ASP.NET Core 1.0

CheapASPNETHostingReview.com | Best and cheap ASP.NET Core 1.0 hosting. Even though the ASP.NET Web platform and ASP.NET project scaffold have undergone some significant changes, ASP.NET MVC Views and Controllers have faced rather minor transformation in comparison with the shift in skeleton of the Application with the new platform. So here’s a brief outline of the latest news in ASP.NET development.

In this article, I’m going to describe the main concepts of building claim-based security on top of a brand-new platform: ASP.NET Core (with .NET Core). At the same time, I will create an application with similar functionality (as was done in my previous article), highlighting the differences.

Let’s get down to work. Create a “Hello World” ASP.NET Core Web application using the .NET Core framework

Claims1

Figure 1: Creating a new ASP.NET Core Web application

Just like in the previous version of ASP.NET MVC, the main job is done. The default Visual Studio .NET Web Project template has already added all the namespaces and assemblies required for our test project. The only thing left is to implement simple functionality to add a new Claim during the user registration/creational process and then apply the authorization restriction to the user with the Claim specified.

Let’s quickly review the most important pieces of functionality responsible for security work this time:

Startup.cs is a class for the entire application bootstrap, including security:

Models\ApplicationUser.cs contains an ApplicationUser class that derives from Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUser:

Until now, it’s been empty, so this is where we should add our claims. Let’s start applying code changes to demonstrate Claim-based security in real life:

1. Enable Entity Framework Migrations

Enable Entity Framework Migrations if there are any iterative changes to Claims planned. Because ASP.NET Identity uses Code First, auto-migration would be useful to perform database schema updates

2. Add Relevant Properties

Add all relevant properties to the ApplicationUser class (in file Models\ApplicationUser.cs) to store the Claims. Let’s take “BirthDate” and add this property to ApplicationUser. Don’t forget to add the using System clause before class definition.

3. Add EF Migration

Add EF migration to the update database with the new field. In the Package Manager Console, perform the following steps:

  1. Add-Migration “Age” <press Enter> to create an upgrade script for our modification.
  2. Update-Database <press Enter> to run a database schema update.

Now, we need to implement the filling out of the Birthday value. To make it more obvious, add a Birthday parameter to the User Registration form in the Models\AccountViewModels\RegisterViewModel.cs RegisterViewModel class:

4. Update the Views\Account\Register.cshtml File

Update the Views\Account\Register.cshtml file with the new field:

5. Update the Controllers\AccountController.cs Register Method

Update the Controllers\AccountController.cs Register method to pass Birthday:

6. Add the Claims

Now, we need to add the Claims. To be more precise, we need a mechanism to add the Claims in ASP.NET Core because Microsoft.AspNetCore.Identity.SignInManager<TUser>, by default, includes only username and user identifier claims. SignInManager<TUser> uses IUserClaimsPrincipalFactory<TUser> to generate ClaimsPrincipal from TUser (in our case, from ApplicationUser).

We need to create our own implementation of IUserClaimsPrincipalFactory<TUser> to add custom claims. To not generate the boilerplate code, simply derive it from the default UserClaimsPrincipalFactory<TUser> which is already implementing IUserClaimsPrincipalFactory<TUser>.

7. Register CustomClaimsPrincipalFactory

We need to register our CustomClaimsPrincipalFactory in Startup.cs after the Identity setup has been added:

8. Verify the Claim

We have implemented the Claims setup. The only thing left is to verify the Claim. It is a common practice to write custom Authorize filters to verify the availability and particular value of the Claim pair, and then put that filter on the controllers’ actions.

Claim BirthDay requires more checks, so I will implement verification of the Claim just for demonstration purposes in the Controllers\HomeController.cs About method:

Any Claim may be extracted easily from the HttpContext.User at any point of the project.

Traditionally, let’s try to verify if the code works.

Reviewing all the Claims (in debug window):

Claims4

Figure 4: Viewing the Claims in the debug window

Conclusion

That was a step-by-step guideline to set up Claim-based security in ASP.NET Core with the help of ASP.NET Core Identity.

Compared to the previous-generation ASP.NET MVC, at first glance implementation of the Claim-based security looks more complicated in ASP.NET Core. Previously, it was possible to add the Claims directly in the ApplicationUser implementation via overriding the GenerateUserIdentityAsync() method. In ASP.NET Core, we need to implement IUserClaimsPrincipalFactory<TUser> that is internally used by SignInManager<TUser>. On the other hand, we’ve got more structured classes and interfaces implementation in ASP.NET Core, as logically SignInManager should indeed control sign-in processes (including claims) and ApplicationUser should be just an IdentityUser.

One more useful thing that was introduced in ASP.NET Core is Claim-Based Authorization on top of Policies. It simplifies the verification of Claims on Controllers and Methods, thereby providing an ability to group the Claims.