我正在使用自定义USERNAME-PASSWORD验证器开发WCF服务。

我有从UserNamePasswordValidator继承的CustomUserNameValidator。

我还使用了从IAuthorizationPolicy继承的CustomAuthorizationPolicy。

定制授权策略的Evaluate方法如下所示:

    // this method gets called after the authentication stage
    public bool Evaluate(EvaluationContext evaluationContext, ref object state)
    {
        // get the authenticated client identity
        IIdentity client = GetClientIdentity(evaluationContext);

        // set the custom principal
        evaluationContext.Properties["Principal"] = new CustomPrincipal(client);

        return true;
    }


如您所见-我在每次对Evaluate的调用中创建了一个新的CustomPrincipal对象(在服务上调用的每个操作中都完成了)。

这是我的CustomPrincipal构造函数的样子:

    public CustomPrincipal(IIdentity identity)
    {
        IdentityObject = identity;
        GetUser(IdentityObject.Name);
        EnsureRoles();
    }


GetUser和确保方法方法进入SQL数据库,以检查用户的角色。

我的问题是-为什么这必须在每次操作中发生?

为什么创建CustomPrincipal时会在每个操作上发生,而不仅仅是在客户端第一次连接到服务时发生?

对于我来说,为什么对服务调用的每个操作都没有意义-“ CustomPrincipal”将进入数据库并重新获取用户及其所有角色...

[更新]
这是我的查询服务界面的样子:

[ServiceContract(Namespace = "http://www.my1fj.com/QueryService/2012/", SessionMode = SessionMode.Required, ProtectionLevel = ProtectionLevel.EncryptAndSign)]
public interface IQueryService
{
     // Some operations
}

最佳答案

我希望您的服务是按呼叫服务,并且在按呼叫服务中,将在每个呼叫中​​进行身份验证检查,但对于按会话服务,则仅在会话开始时(如果打开了安全协商)进行检查。

..from here

不必每次都访问数据库,而是可以将它们缓存在服务中。

更新:

服务是按呼叫/按会话/单次计费,是由应用于服务类的InstanceContextModeServiceBehavior属性决定的。

例如

[ServiceContract]
interface IMyContract {...}

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
class MyService : IMyContract {...}


要了解更多信息,请检查此post
要了解有关InstanceContextMode属性的更多信息,请检查this

10-08 04:01