rama creada apartir de master en j
This commit is contained in:
@@ -8,21 +8,27 @@ namespace adas_core.Authentication.Attributes;
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class AuthorizeRolesAttribute(PermissionEnum.RolesType type) : Attribute, IAuthorizationFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// Performs authorization by ensuring the current user is authenticated and has a role matching the required permission type.
|
||||
/// Responds with an unauthorized result when no user is authenticated, bypasses role checking for the AuthSome permission type,
|
||||
/// and otherwise responds with a forbid result when no user role starts with the permission type value.
|
||||
/// </summary>
|
||||
/// <param name="context">The authorization filter context providing access to the HTTP context and where the authorization result is assigned.</param>
|
||||
public void OnAuthorization(AuthorizationFilterContext context)
|
||||
{
|
||||
var user = context.HttpContext.User;
|
||||
|
||||
if (user.Identity?.IsAuthenticated != true)
|
||||
{
|
||||
context.Result = new UnauthorizedResult();
|
||||
return;
|
||||
var user = context.HttpContext.User;
|
||||
|
||||
if (user.Identity?.IsAuthenticated != true)
|
||||
{
|
||||
context.Result = new UnauthorizedResult();
|
||||
return;
|
||||
}
|
||||
|
||||
var roles = user.Claims.Where(c => c.Type == ClaimTypes.Role);
|
||||
|
||||
if (type == PermissionEnum.RolesType.AuthSome) return;
|
||||
|
||||
var hasRequiredRole = roles.Any(r => r.Value.StartsWith(type.ToString()));
|
||||
if (!hasRequiredRole) context.Result = new ForbidResult();
|
||||
}
|
||||
|
||||
var roles = user.Claims.Where(c => c.Type == ClaimTypes.Role);
|
||||
|
||||
if (type == PermissionEnum.RolesType.AuthSome) return;
|
||||
|
||||
var hasRequiredRole = roles.Any(r => r.Value.StartsWith(type.ToString()));
|
||||
if (!hasRequiredRole) context.Result = new ForbidResult();
|
||||
}
|
||||
}
|
||||
@@ -8,22 +8,26 @@ public class AuthorizePermissionsAttribute(
|
||||
IUserService userService)
|
||||
: Attribute, IAuthorizationFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles authorization by validating the presence of the <c>Displayid</c> request header and ensuring the authenticated user exists in the user service. If the header is missing or the user cannot be found, the request is short-circuited with a <see cref="NotFoundObjectResult"/>.
|
||||
/// </summary>
|
||||
/// <param name="context">The <see cref="AuthorizationFilterContext"/> for the current request, providing access to the HTTP context, user identity, and the ability to set the action result.</param>
|
||||
public void OnAuthorization(AuthorizationFilterContext context)
|
||||
{
|
||||
var user = context.HttpContext.User;
|
||||
|
||||
var userName = user.Identity?.Name ?? string.Empty;
|
||||
var displayIdHeader = context.HttpContext.Request.Headers["Displayid"];
|
||||
|
||||
if (string.IsNullOrEmpty(displayIdHeader.ToString()))
|
||||
{
|
||||
context.Result = new NotFoundObjectResult("displayIdHeader not found reference id doesn't exist on header");
|
||||
return;
|
||||
var user = context.HttpContext.User;
|
||||
|
||||
var userName = user.Identity?.Name ?? string.Empty;
|
||||
var displayIdHeader = context.HttpContext.Request.Headers["Displayid"];
|
||||
|
||||
if (string.IsNullOrEmpty(displayIdHeader.ToString()))
|
||||
{
|
||||
context.Result = new NotFoundObjectResult("displayIdHeader not found reference id doesn't exist on header");
|
||||
return;
|
||||
}
|
||||
|
||||
var userDao = userService.GetUserByUserName(userName).Result;
|
||||
|
||||
if (userDao == null)
|
||||
context.Result = new NotFoundObjectResult("User not found on AuthorizePermissionsAttribute");
|
||||
}
|
||||
|
||||
var userDao = userService.GetUserByUserName(userName).Result;
|
||||
|
||||
if (userDao == null)
|
||||
context.Result = new NotFoundObjectResult("User not found on AuthorizePermissionsAttribute");
|
||||
}
|
||||
}
|
||||
@@ -12,87 +12,94 @@ namespace adas_core.Authentication.Attributes;
|
||||
public class PermissionAuthorizeAttribute(string source, string? resourceIdHeader = null)
|
||||
: AuthorizeAttribute, IAsyncAuthorizationFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// Performs asynchronous authorization by validating the user's roles, username, and source header against the permission service.
|
||||
/// For the <c>Panel</c> source, it verifies that at least one of the user's roles grants access to the panel; for other sources, it requires a resource identifier header (such as <c>DisplayId</c> or <c>UnitId</c>) and checks access to the corresponding resource.
|
||||
/// If any required value is missing or no role grants the needed permission, the response is set to <see cref="ForbidResult"/>.
|
||||
/// </summary>
|
||||
/// <param name="context">The <see cref="AuthorizationFilterContext"/> for the current authorization request, providing access to the HTTP context, services, and the result to set when authorization fails.</param>
|
||||
/// <exception cref="ForbbidenException">Thrown when the <see cref="IPermissionService"/> cannot be resolved from the request services.</exception>
|
||||
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
|
||||
{
|
||||
// Obtener el servicio de permisos.
|
||||
var permissionService = context.HttpContext.RequestServices.GetService<IPermissionService>()
|
||||
?? throw new ForbbidenException(HttpEnum.ErrorMessage.ForbiddenNoPermission);
|
||||
|
||||
var user = context.HttpContext.User;
|
||||
|
||||
// Obtener el header que indica la fuente.
|
||||
var headerSource = context.HttpContext.Request.Headers[source].FirstOrDefault();
|
||||
|
||||
// Obtener el identificador del usuario
|
||||
var username = user.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value;
|
||||
|
||||
// Obtiene la lista de roles (valores) del usuario.
|
||||
var userRoles = user.Claims
|
||||
.Where(c => c.Type == ClaimTypes.Role)
|
||||
.Select(c => c.Value)
|
||||
.ToList();
|
||||
|
||||
// Procesa cada rol: si contiene 2 guiones bajos, elimina el tercer segmento.
|
||||
var processedRoles = userRoles.Select(role =>
|
||||
{
|
||||
var parts = role.Split('_');
|
||||
return parts.Length == 2 ? parts[0] : role;
|
||||
}).ToList();
|
||||
|
||||
// Validar que se tenga al menos un rol, username y headerSource.
|
||||
if (!processedRoles.Any() || string.IsNullOrEmpty(username) || string.IsNullOrEmpty(headerSource))
|
||||
{
|
||||
context.Result = new ForbidResult();
|
||||
return;
|
||||
}
|
||||
|
||||
// Parseamos el header para obtener la fuente.
|
||||
var source1 =
|
||||
(PermissionEnum.SourcePermissionsEnum)Enum.Parse(typeof(PermissionEnum.SourcePermissionsEnum),
|
||||
headerSource);
|
||||
|
||||
var hasPermission = false;
|
||||
|
||||
if (source1 == PermissionEnum.SourcePermissionsEnum.Panel)
|
||||
{
|
||||
// Si la fuente es PANEL, verificamos que alguno de los roles tenga acceso.
|
||||
foreach (var roleStr in processedRoles)
|
||||
// Obtener el servicio de permisos.
|
||||
var permissionService = context.HttpContext.RequestServices.GetService<IPermissionService>()
|
||||
?? throw new ForbbidenException(HttpEnum.ErrorMessage.ForbiddenNoPermission);
|
||||
|
||||
var user = context.HttpContext.User;
|
||||
|
||||
// Obtener el header que indica la fuente.
|
||||
var headerSource = context.HttpContext.Request.Headers[source].FirstOrDefault();
|
||||
|
||||
// Obtener el identificador del usuario
|
||||
var username = user.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value;
|
||||
|
||||
// Obtiene la lista de roles (valores) del usuario.
|
||||
var userRoles = user.Claims
|
||||
.Where(c => c.Type == ClaimTypes.Role)
|
||||
.Select(c => c.Value)
|
||||
.ToList();
|
||||
|
||||
// Procesa cada rol: si contiene 2 guiones bajos, elimina el tercer segmento.
|
||||
var processedRoles = userRoles.Select(role =>
|
||||
{
|
||||
if (!Enum.TryParse(typeof(PermissionEnum.RolesType), roleStr, out var roleObj)) continue;
|
||||
var role = (PermissionEnum.RolesType)roleObj;
|
||||
if (!await permissionService.HasAccessToPanel(username, role, source1)) continue;
|
||||
hasPermission = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!hasPermission) context.Result = new ForbidResult();
|
||||
}
|
||||
else if (resourceIdHeader != null)
|
||||
{
|
||||
// Para otras fuentes, se requiere un header que indique el resourceId.
|
||||
var resourceId = context.HttpContext.Request.Headers[resourceIdHeader].FirstOrDefault();
|
||||
if (string.IsNullOrEmpty(resourceId))
|
||||
var parts = role.Split('_');
|
||||
return parts.Length == 2 ? parts[0] : role;
|
||||
}).ToList();
|
||||
|
||||
// Validar que se tenga al menos un rol, username y headerSource.
|
||||
if (!processedRoles.Any() || string.IsNullOrEmpty(username) || string.IsNullOrEmpty(headerSource))
|
||||
{
|
||||
context.Result = new ForbidResult();
|
||||
return;
|
||||
}
|
||||
|
||||
// Verificar que al menos uno de los roles tenga acceso al recurso.
|
||||
foreach (var roleStr in processedRoles)
|
||||
if (Enum.TryParse(typeof(PermissionEnum.RolesType), roleStr, out var roleObj))
|
||||
|
||||
// Parseamos el header para obtener la fuente.
|
||||
var source1 =
|
||||
(PermissionEnum.SourcePermissionsEnum)Enum.Parse(typeof(PermissionEnum.SourcePermissionsEnum),
|
||||
headerSource);
|
||||
|
||||
var hasPermission = false;
|
||||
|
||||
if (source1 == PermissionEnum.SourcePermissionsEnum.Panel)
|
||||
{
|
||||
// Si la fuente es PANEL, verificamos que alguno de los roles tenga acceso.
|
||||
foreach (var roleStr in processedRoles)
|
||||
{
|
||||
if (!Enum.TryParse(typeof(PermissionEnum.RolesType), roleStr, out var roleObj)) continue;
|
||||
var role = (PermissionEnum.RolesType)roleObj;
|
||||
hasPermission = resourceIdHeader switch
|
||||
{
|
||||
"DisplayId" => await permissionService.HasAccessToDisplay(username, role, source1, resourceId),
|
||||
"UnitId" => await permissionService.HasAccessToUnit(username, role, source1, resourceId),
|
||||
_ => false
|
||||
};
|
||||
if (hasPermission)
|
||||
break;
|
||||
if (!await permissionService.HasAccessToPanel(username, role, source1)) continue;
|
||||
hasPermission = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!hasPermission) context.Result = new ForbidResult();
|
||||
|
||||
if (!hasPermission) context.Result = new ForbidResult();
|
||||
}
|
||||
else if (resourceIdHeader != null)
|
||||
{
|
||||
// Para otras fuentes, se requiere un header que indique el resourceId.
|
||||
var resourceId = context.HttpContext.Request.Headers[resourceIdHeader].FirstOrDefault();
|
||||
if (string.IsNullOrEmpty(resourceId))
|
||||
{
|
||||
context.Result = new ForbidResult();
|
||||
return;
|
||||
}
|
||||
|
||||
// Verificar que al menos uno de los roles tenga acceso al recurso.
|
||||
foreach (var roleStr in processedRoles)
|
||||
if (Enum.TryParse(typeof(PermissionEnum.RolesType), roleStr, out var roleObj))
|
||||
{
|
||||
var role = (PermissionEnum.RolesType)roleObj;
|
||||
hasPermission = resourceIdHeader switch
|
||||
{
|
||||
"DisplayId" => await permissionService.HasAccessToDisplay(username, role, source1, resourceId),
|
||||
"UnitId" => await permissionService.HasAccessToUnit(username, role, source1, resourceId),
|
||||
_ => false
|
||||
};
|
||||
if (hasPermission)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!hasPermission) context.Result = new ForbidResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user