ASP.NET Core MVC : developed role-based authorization
14:04 15 Oct 2023

As I mentioned in the title, I am developing a program on the ASP.NET Core MVC platform. I use IdentityUser and IdentityRole when authorizing in my project.

As you know, when authorizing in this type of authorization, authorization is assigned to the action by opening tags like [Authorize(Roles = "Admin")] on the actions.

But I develop this process further and I have a table with RoleId (string), ControllerName (string), MethodName (string) and State (bool) columns that holds the action methods that the roles are authorized for.

While the program is debugging, it will review this table and according to the id of the role to which the user is connected, it will determine which of the actions in the controller from this table is authorized to access and accordingly redirect it to the AccessDenied page or enter the page.

I would be happy if someone can help me with this. Thanks in advance, good forums.

I created two classes AuthorizationService and AuthorizationMiddleware and placed the necessary code in these classes. I injected these classes into the program in the program.cs file, but I get errors.

------------------------Edit---------------------

    public class CustomAuthorizeAttribute : Attribute, IAuthorizationFilter
    {
        QlabContext _dbContext = new QlabContext();
        private readonly RoleManager _roleManager;
        private readonly UserManager _userManager;

        public CustomAuthorizeAttribute(RoleManager roleManager, UserManager userManager)
        {
            _roleManager = roleManager;
            _userManager = userManager;
        }

        public async void OnAuthorization(AuthorizationFilterContext context)
        {
            string request_controller = context.HttpContext.GetRouteData().Values["controller"].ToString();
            string request_method = context.HttpContext.GetRouteData().Values["Action"].ToString();
            bool state = false; //Initial a flag to indicate pass authorize or not

            var roleMethod = _dbContext.AspNetRoleMethods.Where(w => w.ControllerName == request_controller && w.MethodName == request_method).ToList();
            var userName = context.HttpContext.User.Identity.Name;


            if (context.HttpContext.User.Identity.IsAuthenticated)
            {
                // Giriş yapmış kullanıcının kimliğini alın
                var user = await getUserByName(userName);

                // Kullanıcının rolünü alın
                var userRoles = await getRoleList(user);

                foreach (var roles in userRoles)
                {
                    foreach (var item in roleMethod)
                    {
                        string roleName = getRoleNameById(item.RoleId);

                        if (roles == roleName && request_controller == item.ControllerName && request_method == item.MethodName)
                        {
                            state = item.State;
                            break;
                        }
                    }
                }

                if (state) //if ture ,just continue, pass authorize
                {
                    return;
                }
                else       //if false ,return a 401 result.
                {
                    context.Result = new UnauthorizedResult();
                    context.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                    return;
                }
            }
            else
            {
                context.Result = new JsonResult(new { message = "Kullanıcı Doğrulanamadı" }) { StatusCode = StatusCodes.Status403Forbidden };
                return;
            }
        }

        public async Task> getRoleList(IdentityUser user)
        {
            return await _userManager.GetRolesAsync(user);
        }

        public string getRoleNameById(string roleId)
        {
            var role = _roleManager.Roles.Where(w => w.Id == roleId).FirstOrDefault();
            return role.Name;
        }

        public async Task getUserByName(string userName)
        {
            return await _userManager.FindByNameAsync(userName);
        }
    }

I updated the structure like this. My only problem now is in case the user logs in without authorization;

  else //if false ,return a 401 result.
  {
      context.Result = new UnauthorizedResult();
      context.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
      return;
  }

In the above condition, I need to redirect to the AccessDenied page that I defined in program.cs. Thanks in advance.

asp.net-core asp.net-core-mvc asp.net-core-identity