Собственный атрибут

115
07 декабря 2019, 07:50

Подскажите как это реализуется, ни разу такого не делал. Мне надо, перед методом проверять, имеет ли роль пользователя, разрешения на использования метода. Например, я хочу перед методом ActionIndex написать [Permission(User = user, Permission = "read")], а внутри взять и проверить, ну например:

if (!User.HasPerm(Permission))
    RedirectToAction("AccesDenied");  

Как то так.

Answer 1

Сделал вот так. Возможно не правильно, но работает.

public class PermissionAttribute : TypeFilterAttribute
{
    public PermissionAttribute(string[] permissionCodes) : base(typeof(PermissionFilter))
    {
        Arguments = new object[] { permissionCodes };
    }
}
public class PermissionFilter : IAuthorizationFilter
{
    private ApplicationContext _context;
    readonly string[] _permissionCodes;
    public PermissionFilter(string[] permissionCodes, ApplicationContext context)
    {
        _permissionCodes = permissionCodes;
        _context = context;
    }
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        var userId = context.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
        var userRolesId = _context.UserRoles.Where(ur => ur.UserId == userId).Select(ur => ur.RoleId).ToList();
        var permissionCodes = _context.PermissionsRoles.Where(pr => userRolesId.Contains(pr.RoleId)).Select(pr => pr.Permission.Code).ToArray();
        bool hasPermission = false;
        foreach (var permissionCode in _permissionCodes)
        {
            if (permissionCodes.Contains(permissionCode))
            {
                hasPermission = true;
                break;
            }
        }
        if (!hasPermission)
        {
           context.Result = new ForbidResult();
        }
    }
}  

В контроллере:

[Permission(new string[] { "CreateUser" })]
public IActionResult Index()
{
    return View(_view + RouteData.Values["action"].ToString(), _userManager.Users.ToList()); 
}  

Теперь думаю как сделать проверку в разметке)

Answer 2

Я переделал что бы можно было так же и во view проверять permission. Надеюсь помогу кому то еще кроме себя.
Пример проверки в контроллере:

[Permission(new string[] { "EditUser" })]
public IActionResult Index()
{
    return View(_view + RouteData.Values["action"].ToString(), _userManager.Users.ToList()); 
}  

Пример во вью:

@if (User.IsHasPermission(new string[] {"CreateUser"}))
{
<h2>Работает</h2>
}  

Реализация:
Расширяющий класс:

public static class ClaimsPrincipalExtensions
{
    public static bool IsHasPermission(this ClaimsPrincipal user, string [] PermissionCodes)
    {
        var optionsBuilder = new DbContextOptionsBuilder<ApplicationContext>();
        optionsBuilder.UseSqlServer(Startup.connectingString);
        using (ApplicationContext context = new ApplicationContext(optionsBuilder.Options))
        {
            var userId = user.FindFirstValue(ClaimTypes.NameIdentifier);
            var userRolesId = context.UserRoles.Where(ur => ur.UserId == userId).Select(ur => ur.RoleId).ToList();
            var permissionCodes = context.PermissionsRoles.Where(pr => userRolesId.Contains(pr.RoleId)).Select(pr => pr.Permission.Code).ToArray();
            foreach (var permissionCode in PermissionCodes)
            {
                if (permissionCodes.Contains(permissionCode))
                {
                    return true;
                }
            }
        }
        return false;
    }
}   

Атрибут:

 public class PermissionAttribute : TypeFilterAttribute
    {
        public PermissionAttribute(string[] permissionCodes) : base(typeof(PermissionFilter))
        {
            Arguments = new object[] { permissionCodes };
        }
    }
    public class PermissionFilter : IAuthorizationFilter
    {
        private ApplicationContext _context;
        readonly string[] _permissionCodes;
        public PermissionFilter(string[] permissionCodes, ApplicationContext context)
        {
            _permissionCodes = permissionCodes;
            _context = context;
        }
        public void OnAuthorization(AuthorizationFilterContext context)
        {
            if (!context.HttpContext.User.IsHasPermission(_permissionCodes))
            {
               context.Result = new ForbidResult();
            }
        }
    }
READ ALSO
Почему возникает ошибка при загрузке DLL-файла?

Почему возникает ошибка при загрузке DLL-файла?

При попытке загрузить файл с хоста таким образом

108
Ошибка UnityEditor.BuildPlayerWindow+BuildMethodException

Ошибка UnityEditor.BuildPlayerWindow+BuildMethodException

Знаю эта тема довольно заезженная но, ошибка появилась с ничегоЯ ничего не обновлял, не удалял а просто делал свою прогу

104
Ошибка при конвертации данных Double

Ошибка при конвертации данных Double

Есть данный баланс 1995535 он отображается вот так http://prntscr

111
как задать условие PHP

как задать условие PHP

Как через if проверить есть ли в ShowViewContent('sotbit_seometa_bottom_desc'); какой-нибудь текст, если нет то в else вывести (сео-текст) ? Как это пока выглядит на сайте

132