Как я могу применить безопасность на основе ролей к результатам запроса odata/breezejs?

Мне кажется, что запросы breeze / odata представляют значительный риск для безопасного доступа к данным. Например, предположим, что у меня есть неограниченный объект (U), который связан с ограниченным объектом (R). Я не буду выставлять конечную точку для запроса на R, и я напишу свой клиент для запроса на U без включения связанных R. Но злонамеренный клиент может запросить связанные рупии.

Как мне это предотвратить?

У меня есть пара идей. Но я пока не смог их реализовать, чтобы сказать, работают они или нет. Тем не менее, вот мои идеи:

1) Проверьте каждую полученную сущность - после того, как запрос был выполнен, но до того, как результат будет отправлен клиенту. Но я не знаю, как вставить свой проверочный код (через обратный вызов или что-то еще) в момент между выполнением и отправкой клиенту:(

2) Добавьте смарты в POCO, чтобы проверить наличие ограниченных объектов и свойств в зависимости от роли пользователя. Например, вместо:

class MyThing{
  public string P {get;set;}
}

Я хотел бы что-то вроде этого:

private string _p;
public string P 
{ 
  get 
  { 
    if (UserRoles.HasAny("role-a","role-b"))
      return _p;
    return null; 
  }
  set { _p = value; }
}

Это кажется странным, так как POCO должен быть тупым. POCO должен был бы иметь возможность читать роли пользователя откуда-то... может быть, сеанс HTTP. Я не совсем знаю, как это будет работать.

Я прочитал следующие вопросы / ответы, но они мне не помогают: безопасность на основе ролей в breezejs и EF6, как breeze.js управляет безопасностью и избегает разоблачения бизнес-логики, как обрабатывать авторизацию с помощью Breeze JS?

2 ответа

Вы можете использовать AllowedQueryOptions для предотвращения выполнения клиентом $expand, как описано в этом SO ответе.

Другой способ - использовать ODataQueryOptions в качестве параметра для вашего метода контроллера WebAPI. Это дает вам подробную информацию о предикатах запроса в вашем методе сервера, так что вы можете применять их по мере необходимости, а не позволять WebAPI применять их автоматически. Это позволит вам расширить или нет, основываясь на запросе.

Посмотрите этот ответ и этот ответ, чтобы увидеть, как это работает.

Спасибо всем, кто прочитал мой вопрос, подумал об этом и даже зашел так далеко, что ответил. Но ничто не предложило работать для меня. Итак, я понял это самостоятельно. Я могу реализовать свой вариант № 1, подклассифицировать некоторые классы бриза. Я создаю подкласс EnableBreezeQueryAttribute, чтобы я мог переопределить NewQueryHelper для возврата моего подкласса QueryHelper. Затем я использую свой CustomEnableBreezeQueryAttribute в моих методах обслуживания. Метод ValidateData вызывается с объектами сущности. Я мог потерпеть неудачу в методе, если он содержит ограниченную информацию, или я мог бы убрать ограниченную информацию - разрешив возвращать неограниченную информацию.

public class CustomEnableBreezeQueryAttribute : EnableBreezeQueryAttribute
{
    private class CustomQueryHelper : QueryHelper
    {
        public override IEnumerable PostExecuteQuery(IEnumerable queryResult)
        {
            queryResult = ValidateData(queryResult);
            return base.PostExecuteQuery(queryResult);
        }

        private IEnumerable ValidateData(IEnumerable queryResult)
        {
            //TODO: validate/modify data
        }
    }

    protected override QueryHelper NewQueryHelper()
    {
        return new CustomQueryHelper();
    }
}

Я удивлен тем, как трудно было понять, как это сделать. И что не так просто ввести код на этом этапе. Оставляет меня с мучительными вопросами: я делаю что-то, что не должно быть сделано? Или это действительно дыра в функциональности odata/breeze? Или это то, как все делается в odata/breeze?

Другие вопросы по тегам