To Microservice or not to Microservice – helpful links and resources

Microservices is an approach to application development in which a large application is built as a suite of modular services. Each module supports a specific business goal and uses a simple, well-defined interface to communicate with other modules.

Microservices introduction:

Introduction to Microservices Whitepaper

Microservices pattern

The initial white paper on microservices by Martin Fowler and James Lewis (it is a bit dense, but it highlights the intent of this architecture and it is one of the first whitepapers published on the subject):

Martin Fowler’s whitepaper

Using API gateway to get coarser calls and group microservices:

API Gateway pattern

Foreign Key relationship conundrum:

Foreign Keys and Microservices

Distributed transactions and microservices, how to keep referential integrity:

Distributed Transactions Strategy in Microservices

Netflix whitepaper:

Netflix Architectural Best Practices

IASA Free Resources/Whitepapers:

Why to choose Microservices

Successfully implementing a MSA

And finally, if you have a pluralsight trial subscription and you prefer to watch a video instead of reading a bunch of articles, this course is a good introduction to the pattern, the MSDN Professional subscriptions should include a few courses trial at Pluralsight for free:

Pluralsight Training

Happy design and coding!

Role Based Access Control in ASP.NET MVC

Role Based Access Control in ASP.NET MVC is pretty straight forward. There is also a way to do Claims access control, but the most common way is the authorization of a user based on the roles they have in an organization.

This blog post only explains RBAC using ASP.NET Model-View-Controller framework for web applications.

As a developer, to show or hide action links in a View, depending on the user role you can use the following Razor syntax:

@if (User.IsInRole("Administrator"))
{
...
}

On the Controller class, to avoid access to an action if the user types in the URL directly on the browser, we can annotate the action with the Role check tags.

For example, the following code would limit access to any actions on the AdministrationController to users who are  members of the Administrator group.

[Authorize(Roles = "Administrator")]
public class AdministrationController : Controller
{
}

You can specify multiple roles as a comma separated list;

[Authorize(Roles = "HRManager,Finance")]
public class SalaryController : Controller
{
}

The SalaryController  class above will be only accessible by users who are members of the HRManager role or theFinance role.

If you apply multiple attributes then, a user’s HTTP request, accessing the methods on the controller  must be a member of all the roles specified. The following sample requires that a user must be a member of both the PowerUser and ControlPanelUser role before authorization is granted.

[Authorize(Roles = "PowerUser")]
[Authorize(Roles = "ControlPanelUser")]
public class ControlPanelController : Controller
{
}

You can further limit access by applying additional role authorization attributes at the action level;

[Authorize(Roles = "Administrator, PowerUser")]
public class ControlPanelController : Controller
{
    public ActionResult SetTime()
    {
    }
 
    [Authorize(Roles = "Administrator")]
    public ActionResult ShutDown()
    {
    }
}

In the previous code snippet members of the Administrator role or the PowerUser role can access the controller and the SetTime action, but, only members of the Administrator role can access the ShutDown action.

You can also lock down a controller but allow anonymous, unauthenticated access to individual actions.

[Authorize]
public class ControlPanelController : Controller
{
    public ActionResult SetTime()
    {
    }
 
    [AllowAnonymous]
    public ActionResult Login()
    {
    }
}

There is also a way to use Policies for limiting access, but to keep it simple, since we already have the roles defined, we can use the common RBAC for now until we need something more complex.

When the user requests the URL directly they will get a nasty 401 Unauthorized page from IIS if their request is not Authorized.

The Razor code shown on the first code snippet can be used in the View to show the elements on the View, if the User is part of the Administrators role, but if the requestor (user) is not part of the role, he or she will receive a 401 HTTP Unauthorized response.

We can give them a more friendly page explaining they don’t have permissions to access the resources requested and link them to a request access page.

This is what could be done:

For a 401 you will probably be seeing the standard 401 Unauthorized page, even if you have added 401 to the customerrors section in your web.config. When using IIS and Windows integrated Authentication, the check happens before ASP.NET MVC even sees the request.

By editing the Global.asax file you can redirect to a route created for 401 Unauthorized HTTP response errors, sending the user to the “Unauthorized to see this” View (friendly page). The use case for this scenario would be if someone received a link for a View that requires the user to be authorized but  the user has not completed other steps in the process, such as paperwork needed prior to accessing the secure resource.

In the Global.asax:

void Application_EndRequest(object sender, System.EventArgs e)
{
    // If the user is not authorized to see this page or access this function, send them to the error page.
    if (Response.StatusCode == 401)
    {
        Response.ClearContent();
        Response.RedirectToRoute("ErrorHandler", (RouteTable.Routes["ErrorHandler"] as Route).Defaults);
    }
}

and in the Route.config:

     routes.MapRoute(
               "ErrorHandler",
               "Error/{action}/{errMsg}",
                new { controller = "Error", action = "Unauthorized", errMsg = UrlParameter.Optional }
     );

and in the ErrorController class:

public ViewResult Unauthorized()
{
        //Response.StatusCode = 401; 
        // Do not set this or else you get a redirect loop
        return View();
        //where View is the friendly .cshtml page
}

 

Voila!

Happy coding.