Использование IParameterInspector, чтобы остановить неавторизованного пользователя для чтения данных без надлежащего доступа в WCF

У меня есть служба WCF и несколько операций, где я возвращаю массивы основных элементов poco.

Чтобы смягчить случаи, когда я по ошибке возвращаю элементы, к которым у клиента нет доступа, я планировал использовать IParameterInspector, присоединить его к атрибуту IOperationBehavior и затем проверить доступ на чтение в AfterCall. Если у клиента нет прав на чтение, я выкидываю исключение WebFaultException.

Я использую настраиваемую аутентификацию в своем репозитории элементов (класс обслуживания), и ServiceSecurityContext имеет значение null, когда я вхожу в IParameterInspector.AfterCall, поэтому я не могу использовать это для проверки подлинности клиента для чтения элементов.

У меня вопрос, как мне получить доступ к экземпляру службы (PerCall) в моем методе IParameterInspector.AfterCall?

Я также использую IOperationInvoker, где я делаю настоящую аутентификацию в Invoke-методе (проверьте, какой пользователь или анонимус).

И мне интересно, какая разница между "выходами" и "returnValue" в AfterCall?

public class ParameterInspector : IParameterInspector
{
    public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)
    {
        var items = returnValue as Item[];
        if (items == null) return;
        foreach (var item in items)
        {
            User user = ?
            // Throw if no access
        }
    }

    public object BeforeCall(string operationName, object[] inputs)
    {
        return inputs;
    }
}

public class AuthenticationOperationInvoker : IOperationInvoker
{
    public object Invoke(object instance, object[] inputs, out object[] outputs)
    {
        var repo = instance as RepositoryBase;
        User user;
        repo.Authenticate(out user);
        return _defaultInvoker.Invoke(instance, inputs, out outputs);
    }
}

1 ответ

Вы пробовали OperationContext.Current.ServiceSecurityContext.PrimaryIdentity?

Редактировать:

string MyFunction( AThing something, BThing another ) 

В этом случае returnValue является строкой, возвращаемой MyFunction. На выходе будет что-то и другое.

Сложность в общем подходе, таком как использование инспектора параметров, состоит в том, что он часто варьируется от объекта к объекту, как вы будете определять, разрешено ли пользователю видеть объект или какие свойства ему разрешено видеть.

Подход, который я обычно использовал бы для этого (не зная специфики домена), заключается в том, чтобы передавать идентификационную информацию пользователя в хранилище и иметь хранилище, отвечающее за то, чтобы возвращалась только информация, к которой имеет доступ пользователь.

Возьмите, например, если у вас было следующее:

public class GroupTrip
{
   public string GroupName {get;set;}
   public DateTime Start {get;set;}
   public List<Person> Attendees {get;set;}
   public Person Organizer {get;set;}
   public bool IsStandBy {get;set;}
}

public class Person
{
   public string Name {get;set;}
   public string Phone {get;set;}
}

И вы должны убедиться, что:

  • Вы можете видеть объект группы, только если вы посещаете.
  • Если вы посещаете, вы должны видеть имена других людей, но не их номера телефонов
  • Если вы посещаете, вы должны увидеть имя организатора и номер телефона.
  • Если вы посещаете, вы не должны видеть никого в режиме ожидания
  • Если вы организатор, вы сможете увидеть номер телефона каждого.

Это может быстро стать очень сложным. Помогает перенести сложность в хранилище.

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