WCF:UserNamePasswordValidator验证器

2019-09-29  本文已影响0人  天山的虫

Validator获取请求信息

1.能不能在UserNamePasswordValidator获取OperationContext

答案:不直接可能,具体请参照以下回答
WCFValidator中获取上下文Context和问题

It is not possible. Validation runs in different thread and it doesn't have access to WCF contexts.

2.通过消息拦截器缓存OperationContext

WCF使用消息拦截器获取Context

参考:接口实现日志监控和并发限流

消息拦截类

public class DemoMessageInspector:IDispatchMessageInspector{
  public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext       
      instanceContext){
                //ServiceContext为自己实现的缓存类
                ServiceContext.CurrentAction = request.headers.Action.ToString();
   }
   public void BeforeSendReply(ref Message reply, object correlationState){
                //WCF每个Action结束后要置null
                ServiceContext.CurrentAction = null; 
   }
}

Attribute类:

public class ActionServiceBehaviorAttribute:Attriburte,IServiceBehavior{
            //此处参考引用块的代码
}

Service类

[ActionServiceBehaviorAttribute]
public class ActionService:IAction{
  public void Login(){

  } 
}

然后在验证器除调用ServiceContext缓存的信息即可


-------------------------------------------验证器Validator捕获异常相关问题---------------------------------------------------


验证器Validator

public classUserValidator:UserNamePasswordValidator{
public override void Validate(string username,string password){
  bool flag = UserContext.Validate(username,password);
  if(flag == false){
     Log.error("username or password error!");
  }else{
    Log.info("Login success!");
  }
}

问题描述

最开始的时候,想在验证器抛出异常让客户端捕获,然后实际上来说,所有的异常如果直接在验证器抛出,例如:

public classUserValidator:UserNamePasswordValidator{
public override void Validate(string username,string password){
  bool flag = UserContext.Validate(username,password);
  if(flag == false){
     throw new PasswordException();
  }else{
    Log.info("Login success!");
  }
}

在客户端实际捕获的都是MessageSecurityException异常

解决方案:绕过问题

在网上找了一圈解决方案,最后都没有解决问题,很多都说抛出的异常实在MessageSecurityException的innerException中(例如:WCF身份验证),实际上我实测并没有,我的解决如下:

服务端:

public interface IClient{
  void Login(string username,string password);
}
public class ClientImpl:IClient{
  public void Login(){
    thorw new PasswordException();    
  }
}

客户端:

...
catch{
  if(ex.Message.Contains("PasswordException")){
    //to do something
  }
}
...

总结

说白了就是在真正登陆的WCF接口中抛出异常,然后在客户端去捕获,在做相应的处理,并不是什么高明的办法,如果各位道友有能在UserNamePasswordValidator抛出并在客户端获取的Demo请务必告诉我,谢谢!

上一篇下一篇

猜你喜欢

热点阅读