DEV Community

ramtinmovahed
ramtinmovahed

Posted on

How to configure the authorize attribute for a simpler role-based authentication

The authorize attribute in ASP.NET is quite powerful. You can use it for simple authentication, or you can use it for role-based authentication or policy-based authentication by specifying the supplying roles or policies as parameters.

Depending on the size and scope of a project, you might only need a role-based access control without authorization policy. Also, you might want a resource to be accessible for multiple roles.

The way that authorize attribute is structured is that you need to pass a string to specify the role or policy. You may use constants to prevent hard coding it, but you still need to constantly concatenate a comma "," to add more roles.

With a mix of a lookup dictionary, enums, and inheritance, you can create a custom strongly typed authorize attribute for role-based access control.

First, define your roles in a role helper class like so:

public class RolesHelper
    {
        public static readonly Dictionary<Role, string> RolesDict = new()
        {
            { Role.FullAdmin, "FullAdmin" }
            { Role.ReadOnly, "ReadOnly" },
        };
    }
    public enum Role
    {
        FullAdmin,
        ReadOnly
    }
}
Enter fullscreen mode Exit fullscreen mode

In the code above, we first defined the roles in an enum and then created a lookup dictionary.

** You might be able to simplify that further in the future when c# adds support for discriminated unions by assigning string values directly to enums.

Now its time to implement the custom authorize attribute class like so:

public class CustomRoleAuthorizationAttribute : AuthorizeAttribute
    {
        public CustomRoleAuthorizationAttribute(params Role[] roles)
        {
            List<string> rolesFromDict = new();
            foreach (Role role in roles)
            {
                if (RolesHelper.RolesDict.TryGetValue(role, out string? roleFromDict))
                {
                    rolesFromDict.Add(roleFromDict);
                }
            }
            Roles = string.Join(",", rolesFromDict);
        }
    }
Enter fullscreen mode Exit fullscreen mode

Let's go through the code. We first inherit from the Authorize attribute class. We then create the constructor. In the constructor, we pass the list of roles using the params keyword.

Side note: what is params?
You may recall this keyword if you started building a console application and you might have seen it in the main method. By using this keyword, you can send any number of roles that you want, without creating and putting them into an array first.

The params keyword is important as the attributes are evaluated at the runtime, and we cannot instantiate an array to pass to them (we still can instantiate an object inside an attribute).

We would then loop through the roles and check the dictionary to get the string value of it. Finally, we assign the Roles property to those string values, joined by commas ",".

I hope you find this useful. Thanks for reading!

Top comments (0)