skip to Main Content

I have two roles in my project fetched from Azure AD: User and Admin. I also have different views for each role and two different layouts for each role. The standard startup controller is the Home controller which is also the controller to the main page for user, but I want the startup controller to change if the logged in user is admin. What are best practice to achieve this and what is the best method to maintain scalability in the project. I am just a junior developr so try giving an answer that is easy to understand. Also I am using ASP.NET Core 7.

I have tried setting the startup controller to "Dashboard" which is the main page for admin, and then setting authorization to that controller so only an admin role can access it. Then my idea was to create a redirect to the homecontroller index if the user don’t have acces (is not an admin).

Program.cs

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Dashboard}/{action=Index}/{id?}");

DashboardController.cs
[Authorize(Roles = "Admin")]

2

Answers


  1. If you know how to make this redirect to Home/Index that you said, I think it might be a good solution.

    Another possible solution is to use a custom Action Filter. “Authorize” is an Action Filter already included in the framework, but you can write your own.

    https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/controllers-and-routing/understanding-action-filters-cs

    So, you can create something like [MyCustomActionFilter(Roles = “Admin”)]. This filter would be called on every call to the DashboardController.cs, and you can write the code that you want inside it, like so:

    using Microsoft.AspNetCore.Mvc.Filters;
    
    public class MyCustomActionFilter : ActionFilterAttribute, IActionFilter
    {
        public string Roles { get; set; }
    
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
           //Write the code that verifies the role of the user.
           //If the user is not Admin, then you can redirect to Home/Index like this:
    
           filterContext.Result = new RedirectResult("~/Home/Index");
        }
    }
    

    You can call the filter on every call made to the DashboardController.cs, or specify which actions inside the controller would trigger the filter:

    //call it here to trigger it on every action of the controller
    [MyCustomActionFilter(Roles = "Admin")]
    public class DashboardController : Controller
    {
        //or here if you want to trigger it only for this action
        [MyCustomActionFilter(Roles = "Admin")]
        public IActionResult Index()
        {
        }
    }
    
    Login or Signup to reply.
  2. You can use dynamic route value transformation for "root" address:

    // ...
    builder.Services.AddScoped<RootRouteValueTransformer>();
    // ...
    
    app.MapDynamicControllerRoute<RootRouteValueTransformer>("/");
    app.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
    
    public class RootRouteValueTransformer : DynamicRouteValueTransformer
    {
        public override ValueTask<RouteValueDictionary> TransformAsync(HttpContext httpContext, RouteValueDictionary values)
        {
            values ??= new();
            if (httpContext.User.IsInRole("Admin")) // check the role somehow
            {
                values["controller"] = "Dashboard";
                values["action"] = "Index";
            }
            else
            {
                values["controller"] = "Home";
                values["action"] = "Index";
            }
    
            return new ValueTask<RouteValueDictionary>(values);
        }
    }
    

    Or use custom redirect middleware which will redirect request based on some conditions (like empty route and role).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search