Tengo una API web ASP.NET con un montón de controladores y acciones. Al usar EndpointDataSource , puedo obtener una lista de todos los puntos finales en la API, que se usa durante el inicio para mantener una tabla de Controladores y Acciones. Voy a vincular estos registros a una tabla de roles para poder administrar roles para acciones y controladores específicos sin cambiar el código. Esto permitiría al administrador crear roles personalizados que brinden acceso a estos controladores y acciones. La API ya tiene un mecanismo de autenticación personalizado donde los usuarios se asignan a varios roles, por lo que no puedo usar soluciones "estándar" para la administración de roles. (El proceso de inicio de sesión es un poco complejo).
Entonces, quiero crear un atributo de clase [ClassRole] y un atributo de método [ActionRole] para adjuntar a cualquier acción que deba administrarse a través de roles. Así que tengo este código: [AttributeUsage(AttributeTargets.Class)]
public class ControllerRoleAttribute : Attribute, IAuthorizationFilter { public void OnAuthorization(AuthorizationFilterContext context) { } } [AttributeUsage(AttributeTargets.Method)] public class ActionRoleAttribute : Attribute, IAuthorizationFilter { public void OnAuthorization(AuthorizationFilterContext context) { } } Y estos métodos necesitan hacer algo. Básicamente, la búsqueda en la base de datos del nombre del controlador o el nombre de la acción es sencilla. Pero, ¿cómo obtengo el nombre del controlador y el nombre de la acción de esta clase AuthorizationFilterContext ? Preferiblemente sin tener que analizar una URL o lo que sea.
FYI: ActionRoleAttribute primero validará el rol por parte del controlador antes de validar por acción.
En ambos casos, cuando falla la validación, se generará una excepción personalizada y se registrarán datos adicionales. Esta es también la razón por la que necesito una solución separada. Además, si el usuario actual tiene el estado Admin o SuperAdmin , los roles no se verificarán pero el acceso se otorgará automáticamente.
Esta API tenía bastantes controladores con solo unas pocas acciones cada uno. Cada controlador es una unidad lógica que maneja acciones relacionadas. La mayoría de estas acciones tienen que ver con la gestión de datos y tienden a ser información confidencial. Es un poco complejo, ya que la administración de usuarios en sí misma también lo es, ya que los usuarios se dividen en grupos y subgrupos y los roles se pueden asignar a un usuario específico, un grupo o un subgrupo. Los administradores solo controlan sus propios grupos y subgrupos, mientras que el superadministrador sería yo. Debería ser capaz de hacer todo.
¡Lo que más importa es obtener el nombre del controlador!
La clase AuthorizationFilterContext tiene una propiedad llamada ActionDescriptor que contiene los detalles que necesita. Sin embargo, utiliza una clase derivada que es específica de los controladores, por lo que debe convertirla en un ControllerActionDescriptor para obtener los detalles relevantes. Así que puedes hacer algo como esto:
public void OnAuthorization(AuthorizationFilterContext context) { if (context.ActionDescriptor is ControllerActionDescriptor controllerActionDescriptor) { var actionName = controllerActionDescriptor.ActionName; var controllerName = controllerActionDescriptor.ControllerName; } }