1

我有一个 WCF 服务和几个操作,我返回基本 poco 项目的数组。

为了减轻我错误地返回客户端无权访问的项目的情况,我计划使用 IParameterInspector,将其附加到 IOperationBehavior 属性,然后在 AfterCall 中验证读取访问权限。如果客户端没有读取权限,那么我会抛出 WebFaultException。

我在我的项目存储库(服务类)上使用自定义身份验证,当我输入 IParameterInspector.AfterCall 时 ServiceSecurityContext 为空,因此我无法使用它来检查客户端是否经过身份验证以读取项目。

我的问题是如何在 IParameterInspector.AfterCall 方法中访问服务实例 (PerCall)?

我还在使用 IOperationInvoker,我在 Invoke 方法中进行真正的身份验证(检查什么用户或是否匿名)。

我想知道 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);
    }
}
4

1 回答 1

0

您是否尝试过 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;}
}

您必须确保:

  • 只有在参加时才能看到组对象。
  • 如果您正在参加,您应该能够看到其他人的姓名,但看不到他们的电话号码
  • 如果您参加,您应该能够看到组织者的姓名和电话号码
  • 如果您正在参加,您不应该看到任何待命的人
  • 如果您是组织者,您应该能够看到每个人的电话号码。

它很快就会变得非常复杂。将复杂性推送到存储库会有所帮助。

于 2013-04-17T22:04:57.237 回答