tags:

views:

1666

answers:

6

I am trying to call a method in my service that is as below, from an ASP.NET application.

public bool ValidateUser(string username, string password)
{
    try
    {
        // String CurrentLoggedInWindowsUserName = WindowsIdentity.GetCurrent().Name;
        // //primary identity of the call
        // String CurrentServiceSecurityContextPrimaryIdentityName = 
        //   ServiceSecurityContext.Current.PrimaryIdentity.Name;
        //
    }
    catch (Exception ex)
    {
        FaultExceptionFactory fct = new FaultExceptionFactory();
        throw new FaultException<CustomFaultException>(fct.CreateFaultException(ex));
    }
    return false;
}

The Config for the client end of my service is as below

<binding name="WSHttpBinding_IMembershipService" closeTimeout="00:01:00"
     openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
     bypassProxyOnLocal="false" transactionFlow="false"
     hostNameComparisonMode="StrongWildcard"
     maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
     textEncoding="utf-8" useDefaultWebProxy="false" allowCookies="false">
    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
       maxBytesPerRead="4096" maxNameTableCharCount="16384" />
    <reliableSession ordered="true" inactivityTimeout="00:10:00"
       enabled="false" />
    <security mode="Message">
        <transport clientCredentialType="Windows" proxyCredentialType="None"
         realm="" />
        <message clientCredentialType="Windows" negotiateServiceCredential="true"
         algorithmSuite="Default" establishSecurityContext="true" />
    </security>
</binding>

Problem I keep having is when I call it; I get the following exception message.

Server Error in '/' Application. 

The communication object, System.ServiceModel.Channels.ServiceChannel, 
cannot be used for communication because it is in the Faulted state. 
Description: An unhandled exception occurred during the execution of 
the current web request. Please review the stack trace for more 
information about the error and where it originated in the code. 

Exception Details: System.ServiceModel.CommunicationObjectFaultedException: 
The communication object, System.ServiceModel.Channels.ServiceChannel, 
cannot be used for communication because it is in the Faulted state.

Stack Trace: 

[CommunicationObjectFaultedException: The communication object, 
  System.ServiceModel.Channels.ServiceChannel, cannot be used for 
  communication because it is in the Faulted state.]
   System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, 
         IMessage retMsg) +7596735
   System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, 
         Int32 type) +275
   System.ServiceModel.ICommunicationObject.Close(TimeSpan timeout) +0

   System.ServiceModel.ClientBase`1.System.ServiceModel.ICommunicationObject.
         Close(TimeSpan timeout) +142
   System.ServiceModel.ClientBase`1.Close() +38
   System.ServiceModel.ClientBase`1.System.IDisposable.Dispose() +4
   Controls.Membership.accountLogin.ValidateUserCredentials(String UserName, 
            String Password) in C:\ Petition.WebClient\Controls\
                               Membership\accountLogin.ascx.cs:49
   Controls.Membership.accountLogin.Login1_Authenticate(Object sender, 
             AuthenticateEventArgs e) in C:\ WebClient\ Controls\Membership
                                      \accountLogin.ascx.cs:55

I am not entirely sure why I keep getting this. Just in case, here is how I call my service from the client

private bool ValidateUserCredentials(string UserName, string Password)
{
    bool boolReturnValue = false;

    using(Members.MembershipServiceClient client =
        new Controls.Members.MembershipServiceClient())
    {
        try
        {
            boolReturnValue = client.ValidateUser(UserName, Password);
        }
        catch (FaultException<CustomFaultException> ex)
        {
          throw ex;
        }
    }

    return boolReturnValue;
}

Anyone have any idea what I need to do in this case?

+3  A: 

WCF client proxies are one of the two places in .NET where you should not implement a using block around an instance of a class that implements IDisposable. See Indisposable: WCF Gotcha #1.

OBTW, get rid of the try/catch block around your call in the client. Don't catch an exception unless you can "handle" it somehow, and throwing it again is not "handling" it.

John Saunders
The link above appears to be broken now. Here's an alternative: http://web.archive.org/web/20080803051143/www.iserviceoriented.com/blog/post/Indisposable+-+WCF+Gotcha+1.aspx
Kit
+1  A: 

I used that but now I have run into yet another issue that I somehow feel is related.

My Service is currently hosted on a remote server with no authentication or authorization specified except for security tag in the binding config section on the client side, as below

  <binding name="WSHttpBinding_IMembershipService" closeTimeout="00:01:00"
     openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
     bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
     maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
     textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
     <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
      maxBytesPerRead="4096" maxNameTableCharCount="16384" />
     <reliableSession ordered="true" inactivityTimeout="00:10:00"
      enabled="false" />
     <security mode="Message">
      <transport clientCredentialType="Windows" proxyCredentialType="None"
       realm="" />
      <message clientCredentialType="Windows" negotiateServiceCredential="true"
       algorithmSuite="Default" establishSecurityContext="true" />
     </security>
    </binding>

Now I get this error message

The request for security token could not be satisfied because authentication failed. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.ServiceModel.FaultException: The request for security token could not be satisfied because authentication failed.

Kobojunkie
+1  A: 

Well, with your current client setup, you are expecting to encrypt and sign your messages and send along your Windows credentials as identity.

If the remote server which attempts to handle this request is NOT on the same LAN or doesn't have access to the same Active Directory to validate these user credentials, you'll get this message.

The security settings on the server and the client have to match - e.g. if your server has something like

<security mode="None">

then you have to have the same settings on the client as well. If your server cannot validate the Windows credentials, then don't use them. Either use no security at all (not advisable! except for development/testing), or allow anonymous callers (but still use e.g. message security), or then you have to define a custom mechanism in which the caller can authenticate itself.

Security in WCF is a vast field :-) Here's some links that might help get a grip on the topic:

and for a really complete, but also almost daunting overview of all things security related in WCF, there's the WCF Security Guidance on CodePlex.

Hope this helps get you started!

Marc

marc_s
+2  A: 

I'm sure you're probably aware of this, but if not, WCF tracing could prove helpful in these situations.

Especially in scenarios where code has shipped, is in production, and is not updateable, but an unexpected error is thrown on the server side, e.g. one you haven't specified in the contract.

Also being able to view the message payloads can be invaluable.

To get the traces, turn on WCF tracing in the app.config or equivalent.

It's dependent on where you think the error most likely occurred (client or server, or both) as to where you probably want to turn on tracing.

Then use the Service Trace Viewer tool to open the XML log files it produces.

On my machine it's in C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\SvcTraceViewer.exe, but your location is probably a little different.

See the Service Trace Viewer page on MSDN for more info.

Leon Breedt
A: 

Marc, per your suggestion, I switched to allow anonymous callers but I think I may have messed this up or something because now I cannot even access my service as I get service credentials missing exception on the server end. Am I not doing it write?

     <wsHttpBinding>
    <binding name="AnnonymouswsHttpBinding" maxBufferPoolSize="50000000"
      maxReceivedMessageSize="50000000" messageEncoding="Mtom">
      <readerQuotas maxDepth="500000000" maxStringContentLength="500000000"
        maxArrayLength="500000000" maxBytesPerRead="500000000" maxNameTableCharCount="500000000" />
      <security mode="Message">
        <transport clientCredentialType="None" />
        <message clientCredentialType="None" negotiateServiceCredential="false" />
      </security>
    </binding>
  </wsHttpBinding>
   <behavior name="AnonymousMembersBehavior">
      <serviceAuthorization principalPermissionMode="None"/>
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>

Notice the changes in the second from the first. Now I can't even create a client proxy for my service.

Kobojunkie
A: 

The message : "CommunicationObjectFaultedException" usually happened when You don't apply Dispose to the channels working with Using block, so You only need to add a statement Abort like this: catch (Exception ex) { client.Abort(); }

I hope this can help You.

El_Sit