2016-06-02 2 views
8

TransportWithMessageCredential 보안으로 구성된 WCF 서비스가 있습니다. IAuthorizationPolicy, ServiceAuthenticationManagerServiceAuthorizationManager에 대한 세 가지 구현은 모두 유효하며 효과적입니다. 내가 아는 한WCF 액세스 거부 예외가 CheckAccessCore 이후에 클라이언트에 반환되지 않음

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() }); 

ServiceAuthorizationManager 상속 클래스, CheckAccessCore 방법에서는, return false 문 거부 ​​됨 액세스를 나타냅니다. 클라이언트 측에서는 서비스가 클라이언트에 아무것도 반환하지 않고 서비스 스레드가 정지 된 것으로 보이는 액세스가 거부 된 것을 알기를 원할 때까지는 모든 것이 좋습니다.

클라이언트 쪽에서 모든 종류의 try catch을 시도했지만 작동에 FaultContract을 추가했지만 문제가 발생하지 않습니다.

진단 도구에서 두 가지 오류 이벤트가 표시됩니다.

enter image description here

액세스 거부 오류에 사용자가 서비스를받을 수있는 내 구현 무엇을 통보 누락?

업데이트

그것은 내가 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); 
     } 
    } 

그러나 이벤트가 호출 클라이언트가 늘 디버그 이벤트에 나타납니다 처리되지 않은 예외 '를 제외하고 같은 가져 오기'.

을 : 나는 호출 클라이언트를 실패 할 수 있습니다

유일한 방법은 내가 생각 IDispatchMessageInspectorBeforeSendReply 방법에 예외를 던져 것은 내가 FaultException 대신 클라이언트 측에 CommunicationException를 얻을로 갈 수있는 방법이 아니다

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); 
     } 
    } 

WCF 추적 : 당신은 당신의 A 경우 SecurityAccessDeniedException에서, 여기에 대신 통신 예외를 오류 예외를 기 대해서는 안 enter image description here

+0

당신이 반환 될 당신이 "액세스 거부"오류가 기대하면 어떻게 정확히 명확히 수 있을까? 그리고 아마도 관련 클라이언트 측 코드 중 일부를 게시 할 수 있습니까? 하나의 마지막 생각 : 오류를 반환해야 할 때 매달려있는 스레드는 멀티 스레딩 기이함을 암시합니다. 예외가 트리거/처리되는 방식에 눈에 띄지 않는 교착 상태 또는 경쟁 조건이있을 수 있습니까? –

+0

또한 [this StackOverflow post] (http://stackoverflow.com/questions/17738305/wcf-routing-service-dynamic-error-handling)을 참조하십시오. –

+0

WCF 추적을 켜 봤습니까? 이렇게하면 서버 측에서 진행되는 작업에 대한 자세한 정보를 얻을 수 있습니다. – MvdD

답변

1

. 나는이 단계에서 제기 된 모든 예외가 통신 문제에 관한 것만 큼 통신 일 것이라고 기대할 것이다. 보안 문제도 그 일부이다.

+0

문제가 있습니다. 예외의 유형이 아니라 오히려 예외가 삼킨 것입니다. –

0

다음과 같이 코드 유형을 변경하려고하십시오

<bindings> 
    <wsHttpBinding> 
     <binding name="NoSecurityBinding" > 
      <security mode="None"> 
       <transport clientCredentialType="None"/> 
       <message clientCredentialType="None"/> 
      </security> 
     </binding> 
     <binding name="DefaultBinding" /> 
    </wsHttpBinding> 
</bindings> 
+0

Transport + Message security와 함께 TCP를 사용하고 있습니다. –

+0

으로 시도하십시오. –

관련 문제