Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting 403 Forbidden error. The HTTP request was forbidden with client authentication scheme 'Anonymous'

Tags:

c#

wcf

This issue that I am having doesn't happen for all of the clients that are accessing our services but what is consistent is that when the error does occur, it is happening on the same service call for a handful of clients.

Here are the details of the exception:

System.ServiceModel.Security.MessageSecurityException The HTTP request was forbidden with client authentication scheme 'Anonymous'. System.ServiceModel.Security.MessageSecurityException: The HTTP request was forbidden with client authentication scheme 'Anonymous'. > ---> System.Net.WebException: The remote server returned an error: (403) Forbidden. at System.Net.HttpWebRequest.GetResponse() at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout) --- End of inner exception stack trace --- Server stack trace: at System.ServiceModel.Security.IssuanceTokenProviderBase1.DoNegotiation(TimeSpan timeout) at System.ServiceModel.Security.SspiNegotiationTokenProvider.OnOpen(TimeSpan timeout) at System.ServiceModel.Security.TlsnegoTokenProvider.OnOpen(TimeSpan timeout) at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Security.CommunicationObjectSecurityTokenProvider.Open(TimeSpan timeout) at System.ServiceModel.Security.SecurityUtils.OpenTokenProviderIfRequired(SecurityTokenProvider tokenProvider, TimeSpan timeout) at System.ServiceModel.Security.SymmetricSecurityProtocol.OnOpen(TimeSpan timeout) at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Channels.SecurityChannelFactory1.ClientSecurityChannel1.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.DoOperation(SecuritySessionOperation operation, EndpointAddress target, Uri via, SecurityToken currentToken, TimeSpan timeout) at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.GetTokenCore(TimeSpan timeout) at System.IdentityModel.Selectors.SecurityTokenProvider.GetToken(TimeSpan timeout) at System.ServiceModel.Security.SecuritySessionClientSettings1.ClientSecuritySessionChannel.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade) at System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs) at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) Exception rethrown at [0]: at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) at > Proxy.FileTransferService.IFileTransferService.EstablishProxy(DownloadRequest request) at Proxy.FileTransferService.FileTransferServiceClient. Proxy.FileTransferService.IFileTransferService.EstablishProxy(DownloadRequest request) at NormalFileTransferServiceClient.Download(Int32 packageId, IStreamWriter downloader, Archiver archiver) at LoggingFileTransferServiceClient.Download(Int32 packageId, ISt

That exception is being thrown by the client.

The client proxy configuration for IFileTransferService is:

<binding name="WSHttpBinding_IFileTransferService" 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="Mtom"
  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="UserName" negotiateServiceCredential="true"
      algorithmSuite="Default" establishSecurityContext="true" />
  </security>
</binding>

  <endpoint address="http://[hostname]/FileTransferService.svc/FileTransfer"
    binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IFileTransferService"
    contract="Proxy.FileTransferService.IFileTransferService"
    name="WSHttpBinding_IFileTransferService">
    <identity>
      <certificate encodedValue="a long string"/>
    </identity>
  </endpoint>

The service configuration is

<service behaviorConfiguration="ServiceBehavior" 
    name="Services.FileTransferService">
        <endpoint name="WSHttpBinding_IFileTransferService" 
       binding="wsHttpBinding" 
       bindingConfiguration="MtomWSHttpBinding" 
       contract="Services.IFileTransferService" 
       address="/FileTransfer"/>
        <endpoint binding="basicHttpBinding" 
       bindingConfiguration="FileTransferServicesBinding" 
       contract="Services.IFileTransferService"/>
        <host>
          <baseAddresses>
            <add baseAddress="http://[hostname]/FileTransferService.svc"/>
          </baseAddresses>
        </host>
</service>

<binding name="wsHttpBinding" 
         maxReceivedMessageSize="2147483647" 
         receiveTimeout="5" 
         useDefaultWebProxy="false">
      <readerQuotas maxDepth="2147483647" 
             maxStringContentLength="2147483647" 
             maxArrayLength="2147483647" 
             maxBytesPerRead="2147483647" 
             maxNameTableCharCount="2147483647" />
  <security mode="Message">
    <message clientCredentialType="UserName" />
  </security>
</binding>

<basicHttpBinding>
    <binding name="FileTransferServicesBinding" 
           maxReceivedMessageSize="10067108864" 
           messageEncoding="Mtom" 
           transferMode="Streamed" 
           useDefaultWebProxy="false">
      <security mode="None">
        <message clientCredentialType="UserName" />
      </security>
    </binding>
  </basicHttpBinding>

Note: A few clients are using the basicHttpBinding (if I set everything up correctly). In later release of the client, which may not have been fully distributed (which is why I have to support 2 version), I changed the proxy to use the wsHttpBinding endpoint instead. I'm wondering if this error that I'm getting is specific to basicHttp and if so, maybe I don't have these configurations set up properly. I'm under the assumption that the clients that are getting this 403 error are using the wsHttpBinding.

Here is the code for the service:

public RemoteBinaryInfo EstablishProxy(DownloadRequest request)
{
    int packageId = request.PackageId;

    System.IO.MemoryStream stream = new System.IO.MemoryStream(packageRepository.GetPackageBinary(packageId));

    DisposeStreamWhenOperationIsComplete(stream, OperationContext.Current);

    RemoteBinaryInfo result = new RemoteBinaryInfo();
    result.Length = stream.Length;
    result.MemoryByteStream = stream;
    return result;

}

private static void DisposeStreamWhenOperationIsComplete(System.IO.MemoryStream stream, OperationContext clientContext)
{
    clientContext.OperationCompleted += new EventHandler(delegate(object sender, EventArgs args)
    {
        if (stream != null)
            stream.Dispose();
    });
}

Does any one know if getting rid of this exception is something within my control? Are there any configuration changes that I can make on either the client or service config files?

If you need anymore information from me please let me know.

like image 934
SideFX Avatar asked Oct 19 '11 19:10

SideFX


3 Answers

In my case this error was from our organization's HTTP proxy server. Found it from: MessageSecurityException.InnerException.Response.Headers:

{Mime-Version: 1.0
X-Squid-Error: ERR_ACCESS_DENIED 0
X-Cache: MISS from <
X-Cache-Lookup: NONE from < proxy-server-address>
Proxy-Connection: close
Content-Length: 2165
Content-Type: text/html
Date: Wed, 25 Apr 2012 10:55:39 GMT
Server: squid/3.0.STABLE25
Via: 1.0 < proxy-server-address> (squid/3.0.STABLE25)
}

In my case also it occurred for a file transfer method that transfers file chunks in a byte array of size 16384. On reducing the size to 10000, the error was resolved. This means the proxy server had some kind of size limit set.

On a machine having direct internet access, the file transfer method never failed with this error, even for array size > 16384.

Since only some of your clients are facing this issue, possibly they are behind a firewall / proxy server that is the one actually blocking access and returning this error?

like image 67
amolbk Avatar answered Oct 17 '22 02:10

amolbk


It sounds to me like the clients that are receiving MessageSecurityException are not supplying a valid username/password with their request.

See the following msdn topic http://msdn.microsoft.com/en-us/library/ms733131.aspx

like image 31
Sam Shiles Avatar answered Oct 17 '22 04:10

Sam Shiles


So you have a web service configured in IIS using Anonymous authentication, and you get a 403 forbidden error for only a handful of users.

From my own experience this is normally caused by an access denied exception when accessing an ACL controlled system resource such as the file system.

Every user connected anomalously will have their request processed (assuming IIS 7) by the w3wp.exe process which normally has the application pool identity (IIS APPPOOL/AppPoolName), if that identity is not added to any required access control lists an access denied exception will cause IIS to responded with a 403 error.

I normally add the application pool identity to a group then add the group to any required resources.

If you can't figure out what resources might be causing the exception, try looking in the security event log for “Audit Failure” entries for clues. You may need to configure the local security policy to log security events.

good luck

like image 1
Robert Avatar answered Oct 17 '22 03:10

Robert