I have an application wherein users can make new Roles. Some actions are only accessible by certain roles. To check whether a user is allowed to do a certain action, I use a custom AuthorizeAttribute, similar to https://stackoverflow.com/a/40300184.
[AuthorizeRoles(Permission.Unlink, Permission.Link)]
[HttpGet("link")]
public IActionResult Link(int id)
{
...
}
The AuthorizeRolesAttribute class:
public class AuthorizeRolesAttribute : AuthorizeAttribute
{
public AuthorizeRolesAttribute(params Permission[] permissions)
{
Roles = GetRoles(permissions);
}
}
GetRoles:
public static string GetRoles(params Permission[] permissions)
{
DataRowCollection rows = DatabaseHelper.RoleTable.Rows;
List<string> allowedRoles = new List<string>();
foreach (DataRow row in rows)
{
bool allowed = true;
foreach (Permission permission in permissions)
{
if ((bool)row[permission.ToString()] == false)
allowed = false;
}
//if all required permissions are true in this role it is added to the allowed roles
if (allowed)
allowedRoles.Add(row["ROLE"].ToString());
}
return string.Join(",", allowedRoles);
}
When the application starts, each method with the AuthorizeRolesAttribute calls the GetRoles method to determine what roles are allowed to use the method. This works fine for existing roles, however, when a new role is added. The attribute doesn't re-evaluate the roles. I need the attribute to update and allow the new role to use the method without having to restart the application.
I have tried to run the following code after adding a new Role. (As suggested by https://stackoverflow.com/a/12196932)
typeof(UsersController).GetMethod(nameof(UsersController.Link)).GetCustomAttributes(false);
This does cause the AuthorizeRolesAttribute to call GetRoles() again, and this does return a string with the new Role in it. However, when trying to access the 'Link' method as a user with the new Role, I get a 403 Forbidden status.