Moh*_*hin 8 c# security wcf access-denied wcf-security
我有一个配置了TransportWithMessageCredential安全性的WCF服务.所有三种实现的IAuthorizationPolicy,ServiceAuthenticationManager和ServiceAuthorizationManager到位,有效.
serviceHost.Credentials.ServiceCertificate.SetCertificate("CN=localhost");
serviceHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new CustomValidator();
serviceHost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = System.ServiceModel.Security.UserNamePasswordValidationMode.Custom;
serviceHost.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.Custom;
serviceHost.Authorization.ServiceAuthorizationManager = new MyServiceAuthorizationManager();
serviceHost.Authentication.ServiceAuthenticationManager = new MyServiceAuthenticationManager();
serviceHost.Authorization.ExternalAuthorizationPolicies =
new System.Collections.ObjectModel.ReadOnlyCollection<System.IdentityModel.Policy.IAuthorizationPolicy>(
new MyAuthorizationPolicy[] { new MyAuthorizationPolicy() });
Run Code Online (Sandbox Code Playgroud)
据我所知,在ServiceAuthorizationManager继承的类中,在CheckAccessCore方法中,return false语句表示拒绝访问.这一切都很好,直到我希望客户端知道他有一个访问被拒绝的异常,其中服务停止向客户端返回任何内容,似乎服务线程被绞死.
我尝试了各种各样try catch的客户端甚至添加了一个FaultContract操作,但问题抵制.
我只能看到诊断工具中的两个错误事件.
我的实现中缺少什么来获取服务通知用户访问被拒绝错误?
更新
值得注意的是,我说我正在使用RoutingService,现在我猜真正的原因RoutingService是以某种方式吃异常,但我不知道究竟发生了什么.即使我介入了所有可能的方法,但我没有找到它.
更新2
我IErrorHandler到位了:
public class ServiceErrorHandler : IErrorHandler
{
public bool HandleError(Exception error)
{
//You can log th message if you want.
return true;
}
public void ProvideFault(Exception error, MessageVersion version, ref Message msg)
{
if (error is FaultException)
return;
FaultException faultException = new FaultException(error.Message);
MessageFault messageFault = faultException.CreateMessageFault();
msg = Message.CreateMessage(version, messageFault, faultException.Action);
}
}
Run Code Online (Sandbox Code Playgroud)
但是事件与调用客户端不会得到异常,并且调试事件中将出现相同的"未处理异常".
我可以通过调用客户端失败的唯一方法是在BeforeSendReply方法中抛出一个异常IDispatchMessageInspector,我认为这不是一种方法,因为我CommunicationException在客户端而不是FaultException:
public void BeforeSendReply(ref Message reply, object correlationState)
{
if (reply != null && reply.IsFault)
{
var messageFault = MessageFault.CreateFault(reply, Int32.MaxValue);
throw new FaultException("Access was denied", messageFault.Code);
}
}
Run Code Online (Sandbox Code Playgroud)
您不应该期望这里出现FaultException,而是通信异常,在您的情况下是SecurityAccessDeniedException。我希望现阶段提出的所有例外情况都是通信问题,因为它涉及通信问题,安全问题是其中的一部分。