Как сделать авторизацию для конкретного поля в конкретном объекте в ASP.Net Core? - PullRequest
0 голосов
/ 12 октября 2018

Мне нужно проверить привилегии для определенного поля в конкретном объекте в базе данных.

Давайте сделаем и пример.У меня есть Модель с именем Employee

public class Employee {

    [Key]
    public int EmployeeID { get; set; }

    public string JobTitle { get; set; }

    public string Description { get; set; }

    public int Salary { get; set; } // <---- Restricted

    public int BossID { get; set; }
}

И у меня есть несколько случаев:

  1. Мне нужно ограничить доступ к определенному полю Salary, потому что я нене хочу, чтобы кто-то видел зарплату друг друга.Но HR может видеть любого Salary и редактировать его.Если я этот сотрудник, я могу видеть свой собственный Salary, но не могу его редактировать.

  2. Каждый может видеть названия должностей друг друга, но редактировать его может только HR.А также начальник этого сотрудника, может редактировать, сам сотрудник не может.

Вариант использования:

  • Я менеджер с RoleID 4.Я хочу видеть Salary моего Employee по имени Джон Смит с EmployeeID 5. Я могу это сделать.

  • Я менеджер с RoleID 4. Я хочу видетьSalary из 'Employee named Mark Twain with EmployeeID` 8. Марк не является моим непосредственным подчиненным.Он из другой ветки.Я не могу этого сделать.

  • Я работаю с EmployeeID 5 и хочу увидеть свой Salary.Это разрешено.

  • Я работаю с EmployeeID 5 и хочу отредактировать свою собственную Salary.Это запрещено.Я получаю HTTP-ошибку 401.

  • Я из отдела кадров.Я могу видеть и редактировать Salary всех сотрудников в компании.

Я думаю, что-то вроде этого:

public class Access {
  [Required]
  public int RoleID { get; set; }

  [Required]
  public string TableName { get; set; }

  [Required]
  public string ColumnName { get; set; }

  [Required]
  public int RowID { get; set; }
}

И затем проверять (по Authorizeатрибут), если конкретная роль (начальник, HR или что-то) имеет доступ к конкретному полю (например, Salary) для конкретных данных (например, Employee с идентификатором 22).Кстати, это много "специфического".

Как мне это сделать?Моя идея «ОК»?

1 Ответ

0 голосов
/ 12 октября 2018

Вы должны реализовать 2 разных метода.Один для HR при запросе данных, а другой для простого пользователя.Тогда вам никогда не следует возвращать весь объект (json), вместо этого создайте несколько DTO (Data Transfer Object), которые содержат желаемые данные.Итак, давайте создадим пример:

public class DTOGetEmployeeByEmployee {

    public int EmployeeID { get; set; }

    public string JobTitle { get; set; }

    public string Description { get; set; }

    public int BossID { get; set; }
}

public class DTOGetEmployeeByHR {

    public int EmployeeID { get; set; }

    public string JobTitle { get; set; }

    public string Description { get; set; }

    public int Salary { get; set; }

    public int BossID { get; set; }
}

Как только пользователь запросит этого сотрудника, получите его из базы данных, а затем преобразуйте в желаемый DTO.Наилучший способ, который я видел до сих пор, - это использовать AutoMapper:

Mapper.Map<DTOxxxx>(yourObject);

. Вы также можете использовать атрибут [Authorize], чтобы проверить, является ли пользователь персоналом или сотрудником.Я делал это несколько раз в сочетании с JWT-токеном.

public class EmployeeController
{
    [Authorize("HR")]
    [HttpGet, Route("GetForHR")]
    public IActionResult Get(int employeeID)
    {
        // Note: this is just a sample out of my head, so there will be adjustments needed in order to run that

        // Check if the HR is allowed to access the Employees data

        // Get the Employee by its ID
        var emp = ...;

        // Convert it to the DTO
        var dto = Mapper.Map<DTOGetEmployee>(emp);

        // return the dto
        return Ok(dto);
    }
}

Могу поспорить, что существует множество лучших решений, но для меня это очень просто, бесполезно переопределять в других приложениях и нетощутимая потеря производительности

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...