Security is HARD…

What can I say, we all know it’s true, if it was easy then there would be a lot more devs doing things correctly and a lot less data breeches these days.

Sometimes though, it seems like our development platform providers makes things far more difficult than they need to be, case fact was my experience recently with dotnet core and a blazor server side application…

Those of you who are used to using ASP.NET MVC, and the classic MS Web application way of adding user roles, to authorize pages will remember the good old “Authorize” attribute, an attribute that’s super easy to drop at the top of a page and add some roles to it:

[Authorize(Roles=”SALES, PURCHASING”)]

Very easy, very straight forward, and as long as you used asp.net identity framework to handle your user sign in you where golden, everything just worked, all you needed to was make sure the user sign in had one or more “ROLE” claims on the sign-in session and everything just worked.

It was also amazingly easy to customize, if the Authorize attribute didn’t quite work the way you needed it to, then all you had to do was create a custom c-sharp class that inherited from the AuthorizeAttribute class, and then put your custom implementation in an override of the “AuthorizeCore” method, and life was great.

Blazor Enters the Scene

That was until Blazor came around. Don’t get me wrong, I love Blazor esp Server Side, it’s a great technology for doing SPA’s using nothing but C#, but there are just a few teensy choices the team have made on established API’s that I don’t quite agree with, and well… AuthorizeAttribute is one of them.

You see, the AuthorizeAttribute that graces the runtime now is nothing more than a hollow shell of it’s former self, in fact if you take out all the comments and spacing in the code, it’s now only about 12 lines long, you can see the entire file in the dot net repo, right here:

aspnetcore/AuthorizeAttribute.cs

Even the IAuthorizeData that it inherits from is rather anaemic, at a paltry 6 lines long once you remove all the fluff from it.

All of this also means that there is no longer an AuthorizeCore to override, nor is there any other meat to get stuck into and make use of, there is quite literally a constructor, and a bunch of local variables, and that’s it.

The funny part is though, the Authorize attribute still works, if you specify it using the old syntax, and even give it some roles, it will apply those roles to your page and protect your page just as it always has, there has to be some magic somewhere right?

Bring on the Policy’s

If you search MS docs and all the usual places for information on this, you’ll find there’s a new interface in town, an interface that uses something called “Policys”, and indeed if you look at the source code for the authorize attribute, you’ll see that it still has one constructor that takes a string called a “Policy”:

The old stalwarts however, “Roles” and “AuthenticationSchemes” are now relegated to global variables on the class.

On the surface, policy’s are actually very, very useful and after studying the docs I can actually see how you would make use of them, you essentially register the policy objects you want to use in your Startup.cs:

Then you write a policy handler something like the following example:
and then you register that policy using the good old Authorize attribute, either using @attribute on the page, or in code, something like the following:
(All the code snippets above are images by the way, so apologies to those trying to click ‘copy’ and get a code copy, word press seems to have a lot of trouble with copied code segments, so it’s easier to screen grab code when writing)

All the code above came from the actual Microsoft doc’s page on the subject here:

Policy-based authorization in ASP.NET Core | Microsoft Docs

So what’s the problem?

Astute are we dear reader, how’d you guess there was a problem with all of this? 🙂

The problem with it all, is there is no way to pass parameters from the usage of the policy at run time, into the policy.

The simplicity of using the AuthorizeAttribute meant that it was simple to grab the roles, modify them, poke them back in where they needed to be and everything still worked as expected.

With a policy, as you can see from the above Microsoft code examples, you can pass in parameters at instantiation time, in the Startup class, but you cannot modify those parameters, or indeed any parameters at the point where you use the policy in the page itself, as the policy name is just a string. It’s a string that generally has to match the name you register in the Startup class, if it does not, then you generally get a big old exception screen, screaming blue murder at you.

So what do you do, if you need to pass in runtime parameters? I mean surely, you can’t be expected to write one policy for every possible eventuality right?

Well, you can write “requirements”, then you can combine groups of “requirements” into a single policy, that does help aleviate things somewhat, but it’s still not a perfect solution.

In my case, what I needed to do was continue to use the page attribute in the same manner as I always had, namely:

@attribute [Authorize(Roles=”ROLE1, ROLE2, ROLE3″)]

But if the signed in user had an “ADMIN” role on their account, then all that was bypassed, because “ADMIN” has access to everything.

This scenario would have been trivial to implement using the old AuthorizeAttribute way of working.

Determined to crack this thing however, the first place I turned to was the first port of call I always turn to, the gitter blazor group:

https://gitter.im/aspnet/Blazor

After a bit of to & fro with the regulars, such as “Chucker”, “SQL-magoo” and a few others, I found out that someone had been asking a similar question earlier on in the day, so I went and chased down that code, then as I was about to sign off for the night I got talking to “Rockford Lhotka”, who mentioned he’d previously solved a very similar problem, using the authorize attribute to pass his data in, and a policy to grab the data and parse it.

This seemed interesting, and by this point I had several possible points of attack, and a fresh set of ideas to work with.

So during the Friday, I set about reading up on everything new I’d uncovered, and boy… what a mess, there are snippets of info everywhere, some of it makes sense, some of it does not, Rockford’s code for example I understood but was missing a vital piece “The Custom Authorize Policy Provider” (Which we’ll come back to in a minute), then there was countless half working authorize attribute implementations dotted around the web, which all seemed to set policy names but little else, and on top of that I even pinged head ASP.NET security guru @blowdart on Twitter and asked for his input, at which point he pointed me to his policy workshop on GitHub (blowdart/AspNetAuthorizationWorkshop) , which filled in yet a few more gaps.

I needed a break!

So I left it for the weekend, let my mind mull things over, and came back to it today (Monday 5th July) and in the process stumbled over an article on Microsoft docs called “Custom Authorization Policy Providers using IAuthorizationPolicyProvider in ASP.NET Core” which can be found here:

Custom Authorization Policy Providers in ASP.NET Core | Microsoft Docs

This was the document that dropped the pennies, and filled in the bit of the puzzle I’d been missing, the all magic “IAuthorizationPolicyProvider” and the thing that is single headedly responsible for making the magic in the new version of the AuthorizeAttribute work too!

Basically, the process goes something like this

  1. You create a custom AuthorizeAttribute , but instead of overriding the code, you add your own properties to it, and you use a classic getter, setter pattern to pack your constructor parameters into a string, then you assign that string to the “Policy” variable that comes as part of the Attribute interface.
  2. You create a custom IAuthorizationPolicyProvider that understands the string you have packed into the policy string, and which then unpacks it, and uses those parameters to set up a policy and/or requirement object for the page in question, before assigning it and returning.
  3. You register the custom policy provider as a Singleton in the dotnet DI provider, replacing the built in one that is used to match policy names to class names.
  4. You decorate the pages that matter with your new custom authorize attribute and everything just works.

So how does this look in practice?

For my solution, I implemented my custom authorize attribute as follows:


using Microsoft.AspNetCore.Authorization;

namespace myapp.PageAttributes
{
  public class CustomAuthorizeAttribute : AuthorizeAttribute
  {
    private const string POLICY_PREFIX = "CustomAuth";

    public CustomAuthorizeAttribute(string pageRoles) => PageRoles = pageRoles;

    public string PageRoles
    {
      get
      {
        if (string.IsNullOrEmpty(Policy)) return default(string);
        
        var temp = Policy.Split('|');
        if (temp.Length != 2) return default(string);

        return temp[0] == POLICY_PREFIX ? temp[1].Trim() : default(string);
      }

      set => Policy = $"{POLICY_PREFIX}|{value}";
    }

  }
}

If I then pass in a set of roles such as:

“ROLE1, ROLE2”

Into my constructor, then this will populate the “Policy” variable with the following string:

“CustomAuth|ROLE1, ROLE2”

As you can see, that clearly is not a valid identifier name, so it’s going to fail if you try and use it right now, as the default policy provider will bawk and cough up an fur ball of exception goodness, complaining that it cannot find a policy with such a bizarre name.

The next part therefore has to be the policy provider itself:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authorization.Infrastructure;
using Microsoft.Extensions.Options;

namespace myapp.AuthorizationRequirements
{
  public class CustomAutorizationPolicyProvider : IAuthorizationPolicyProvider
  {
    private const string POLICY_PREFIX = "CustomAuth";
    private const string ALWAYS_ALLOWED_ROLE = "Administrator";
    
    private DefaultAuthorizationPolicyProvider BackupPolicyProvider { get; }
    
    public CustomAutorizationPolicyProvider(IOptions options)
    {
      BackupPolicyProvider = new DefaultAuthorizationPolicyProvider(options);
    }
    
    public Task GetPolicyAsync(string policyName)
    {
      if (policyName.StartsWith(POLICY_PREFIX, StringComparison.OrdinalIgnoreCase))
      {
        // It's our Custom Auth policy, so we process it
        var temp = policyName.Split('|');
        var roles = temp[1];
        List rolesList = roles.Split(',').Select(r => r.Trim()).ToList();
        if (!rolesList.Contains(ALWAYS_ALLOWED_ROLE))
        {
          rolesList.Add(ALWAYS_ALLOWED_ROLE);
        }
        var policy = new AuthorizationPolicyBuilder(CookieAuthenticationDefaults.AuthenticationScheme);
        policy.AddRequirements(new RolesAuthorizationRequirement(rolesList));
        return Task.FromResult(policy.Build());
      }
      
      // This is failure, if we get here, it was not our policy string.
      // so we delegate it to the default system policy provider
      return BackupPolicyProvider.GetPolicyAsync(policyName);
    }
    
    public Task GetDefaultPolicyAsync() => 
      Task.FromResult(
        new AuthorizationPolicyBuilder(CookieAuthenticationDefaults.AuthenticationScheme)
        .RequireAuthenticatedUser()
        .Build());

    public Task GetFallbackPolicyAsync() => 
      Task.FromResult(null);
    
  }
}

The code looks quite complicated, but it’s actually quite simple once you read through it.

The meat of the operation is in the “GetPolicyAsync” call. It’s this method that get’s passed your custom policy string from the attribute. You then unpack this string, and do what ever you need to with it.

In my case, I unpacked it, de-serialized the roles string into a string list, trimming off all the whitespace in the process, then checked the list to see if my admin role was present and if not add it.

At that point I could add a policy requirement of any requirement I had in the system, including ones I’d written myself, but since all I was interested in was emulating the old fashioned role based access, I simply just used the built in “RolesAuthorizationRequirement” which is now what handles the old AuthorizeAttribute in it’s trimmed down state.

The final part of the method, simply sets up a default authentication scheme, creates a policy builder, builds a policy object consisting of the built in role provider, then returns the builder as a result.

If the policy string is not yours then you have 2 choices.

You either return “Task.FromResult(null)” in which case auth fails instantly, or you return the default policy in the form of a backup provider, which you take as a dependency in your policy providers constructor.

The other two methods you need to implement are for handling defaults and backups, such as if called before your policy decoder is registered, things like that. If I’m honest, I just read up on the MS advice for implementing them and did the default thing, and you should too 🙂 It’s easier, and as the title suggests….

Once you register it in your Startup class in the configure services method using:

services.AddSingleton<IAuthorizationPolicyProvider, CustomAutorizationPolicyProvider>();

Then you can start to use your attribute just as you would normally:

@attribute [CustomAuthorize(“Role1, Role2, Role3”)]

There are NO restrictions to how you pack data into the policy string, as long as your custom policy provider knows how to unpack it, this is why it’s good practice to use a “POLICY_PREFIX” as I have (And as all the MS examples show), you can ONLY register one custom policy provider at a time, so if you have several policy requirements and authorize attributes to deal with, you can easily recognise which is which.

You could also easily put roles and policy’s in a database too, and extract them depending on a given marker, I’m going to be experimenting with this idea in the future, I have an idea or two for a mini Blazor based CMS system.

For now however, challenge accepted, hair torn out and solution produced….

I’d call that a good couple of days work.

The MS docs article on the subject can be found here: Custom Authorization Policy Providers in ASP.NET Core | Microsoft Docs

Shawty

Using a Full Framework SQL Server Project in a .NET core project build.

In this world of EFCore and migrations support that we have now, it’s hard to remember that at one time the primary means of performing SQL server database builds and changes was to use an “SQL Server” project type in visual studio.

In fact many newer devs who are only used to dotnet core might never have even seen the project type that I’m on about

Screenshot 2020-08-26 185627
Continue reading “Using a Full Framework SQL Server Project in a .NET core project build.”

A Little bit of Electronics Madness……

There’s a reason many of the members of my family call me a “Mad Professor”, ever since I was little I’ve had a habit of doing extreme experiments with electronics, and trying to use things in a way they where never really intended to be used.

On top of that, many folks that know me and/or follow my socials, know me better for my software exploits mostly using Microsoft’s .NET framework.

What many don’t know is that my degree is not actually in software, well not entirely anyway,
Continue reading “A Little bit of Electronics Madness……”

Making Blazor validation play nice with Bootstrap 4

There’s no doubt about it, blazor’s forms module and it’s validation features are fantastic.

You get all the benefits of using validation attributes on your models, along with a very fluid and real time UI model that works exactly the same in server and client modes.

There is however, one small problem with it all “Class Names

Continue reading “Making Blazor validation play nice with Bootstrap 4”

Rediscovering Postgres and EF core

Its ok folks, you can relax, yes I’m not ill, yes I have gotten around to writing another blog post, yes I know…. I don’t write enough anymore and I should 🙂

With that out the way, why am I suddenly getting all excited about Postgres and EF again (specifically EF core)

Continue reading “Rediscovering Postgres and EF core”

Pure HTML Validation in Blazor

There’s been a lot of talk about Validation in the Blazor gitter chat recently.

The Blazor dev team have added some validation routines in that closley mimic the way validation works in ASP.NET MVC and many folks have been playing with them to see what they can do with them.

Chris Sainty has even produced a blog post [https://chrissainty.com/using-fluentvalidation-for-forms-validation-in-razor-components/] showing how to wire in the “Fluent Validation” libraries to make form validation even more awesome.
Continue reading “Pure HTML Validation in Blazor”

Bootstrap 4 Succinctly Released

The 8th book Iv’e written to date for Syncfusion’s ever popular Succinctly eBook series, and the third one one Bootstrap.

As Bootstrap continually gets better and more feature rich, then there is a need to keep up to date with the latest offerings it provides.

In this book, I take you on a just over 100 page tour of what’s new, and what it can now do (Hint: Flexbox rules!!!) and show you how to produce some interesting layouts.

Best part about it all is it’s free!!!

You can grab a copy here: Succinctly eBooks

 

Typescript for the C# developer

Over the past couple of years, my most popular talk that Iv’e taken around user groups has been the one where I describe what Typescript is, and how it relates to the backend C# developer.

Iv’e found that many back-end devs who would like to jump into client side development, are often put off from doing so simply beacuse of the percieved mess that the JavaScript eco system is in at present, and let’s be fair it’s not a compleatly unfounded reason either, beacuse JavaScript is bleeding at the edges in a great many places.
Continue reading “Typescript for the C# developer”