Skip to main content

How to Implement single authorization policy in ASP.NET Core 2.0

Along with role-based and claim based authorization, ASP.NET Core also supports the policy-based authorization. A policy is nothing but a collection of requirements with different data parameters to evaluate the user Identity. Read more about the policy-based authorization here. This short post shows how to implement single authorization policy in ASP.NET Core 2.0 application. Once implemented, the policy becomes global and applicable to the whole application.

To implement single authorization policy, open Startup.cs and add the following code in the ConfigureServices method to enable authorization for all the controllers (be it MVC or API).

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(o =>
    {
        var policy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .Build();

        o.Filters.Add(new AuthorizeFilter(policy));
    });
}

This code ensures that every page will require authentication as the policy will demand the user to be authenticated. Only the actions marked with [AllowAnonymous] can be accessed.

The above code block will enable authorization for all the environments (Development, staging or production). However, you don’t want the same behavior in the development environment as it can increase the testing efforts. It would be appropriate to exclude the development environment. To exclude development environment, we need to check for the environment and write code accordingly. To do that, let’s modify the ConfigureServices method to take IHostingEnvironment service and check for the development environment. Like:

public void ConfigureServices(IServiceCollection services, IHostingEnvironment env)
{
    if (!env.IsDevelopment())
    {
        services.AddMvc(o =>
        {
            var policy = new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .Build();
            o.Filters.Add(new AuthorizeFilter(policy));
        });
    }
    else
        services.AddMvc();
}

Save the changes and run the application. And you should be surprised to see the following exception message in the browser.

“The ConfigureServices method must either be parameterless or take only one parameter of type IServiceCollection.”

The message clearly says, the ConfigureServices method either should be with no parameters or with only one parameter. Therefore, we can’t directly inject the IHostingEnvironment in the ConfigureServices method. Then, the question is how do we make it available in the ConfigureServices method?

Well, we can inject the IHostingEnvironment service in the Startup class constructor and store it in a variable. The existing Startup class constructor creates the IConfigurationRoot using a ConfigurationBuilder and saves it to a property on Startup called Configuration. We can take the same approach for IHostingEnvironment by saving it to a property on Startup, for use later in ConfigureServices. The Startup class constructor would look something like this:

public Startup(IConfiguration configuration, IHostingEnvironment env)
{
    Configuration = configuration;
    HostingEnvironment = env;
}

public IConfiguration Configuration { get; }
public IHostingEnvironment HostingEnvironment { get; }

Next, we can use the HostingEnvironment variable in ConfigureServices method to check for the environment. We’ll enable the authorization only for environments other than development.

public void ConfigureServices(IServiceCollection services)
{
    if (!HostingEnvironment.IsDevelopment())
    {
        services.AddMvc(o =>
        {
            var policy = new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .Build();
            o.Filters.Add(new AuthorizeFilter(policy));
        });
    }
    else
        services.AddMvc();
}

Bonus Tip: If you are already using either JWT or OAuth authentication for your application and wish to disable authentication in the development environment, then use the following code in ConfigureServices method.

if (HostingEnvironment.IsDevelopment()) {
   services.AddMvc(opts =>
   {
      opts.Filters.Add(new AllowAnonymousFilter());
   });
} else {
   services.AddMvc();
}

That’s it.

To summarize, the technique shown above helps you to implement single authorization policy globally in ASP.NET Core 2.0 apps. You can easily enable it only for the staging or production environment.

Thank you for reading. Keep visiting this blog and share this in your network. Please put your thoughts and feedback in the comments section.

PS: If you found this content valuable and want to return the favour, then Buy Me A Coffee

One thought to “How to Implement single authorization policy in ASP.NET Core 2.0”

Leave a Reply

Your email address will not be published. Required fields are marked *