Call WCF with windows authentication from SWAGGER-UI - wcf

I have a WCF REST service that uses windows authentication here is the configuration:
<webHttpBinding>
<binding name="web_authenticate_binding" maxReceivedMessageSize="2147483647">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
<readerQuotas maxDepth="128" maxStringContentLength="2147483647" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</binding>
</webHttpBinding>
I am trying to use SWAGGER-UI (and SWAGGER Editor) to invoke this REST service but when I invoke the service I get 401 Unauthorized as expected, because I am not sending my windows credentials.
How can I send my windows credentials to the SWAGGER-UI or give it as parameter so everyone can pass its own credentials?

If you want that someone passes his own credentials, you will need to change the clientCredentialType. This reference may help: https://msdn.microsoft.com/en-us/library/ms733836(v=vs.110).aspx.
The Basic authentication type is probably the simplest one, but it depends if it is suitable for you.

Related

Can I convert this wsHttpBinding to a custom WCF binding that supports streaming?

I'm not very familiar with WCF, but I recently inherited an old API that uses two versions of the following wsHttpBinding, and I've been tasked with adding a new API call to it that uses streaming.
<wsHttpBinding>
<binding name="wsHttpBinding" maxReceivedMessageSize="2147483647" maxBufferPoolSize="0" receiveTimeout="05:00:00" sendTimeout="05:00:00">
<readerQuotas maxArrayLength="2147483647" maxNameTableCharCount="2147483647" maxStringContentLength="2147483647" maxDepth="64" maxBytesPerRead="66560" />
<security mode="None/Transport">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
</security>
</binding>
</wsHttpBinding>
Note: The version for QA uses security mode None, while the version for prod uses security mode Transport, but otherwise they're the same.
While streaming is not supported for this type of binding, it appears that reliable sessions are not currently being used (assuming the lack of a <reliableSession> element means it's disabled), so I'm wondering if it might be possible to convert this to a customBinding that works identically but with streaming enabled for the one call that will use it.
I've seen similar questions answered long ago with BindingBox, a seemingly very useful tool that is no longer available. I unfortunately haven't been able to find a mirror or the source code, so without this tool, how can I determine if this custom binding is possible, and if so, go about creating it?
After a lot of searching, I pieced together the following based on this very old blog post and the customBinding documentation. This is the equivalent of None security mode; for Transport security mode, just replace the httpTransport element name with httpsTransport.
<customBinding>
<binding name="wsHttpStreamBinding" receiveTimeout="05:00:00" sendTimeout="05:00:00">
<textMessageEncoding>
<readerQuotas maxArrayLength="2147483647" maxNameTableCharCount="2147483647" maxStringContentLength="2147483647" maxDepth="64" maxBytesPerRead="66560" />
</textMessageEncoding>
<httpTransport transferMode="Streamed" maxReceivedMessageSize="2147483647" maxBufferSize="104857600" />
</binding>
</customBinding>

WCF streaming with windows authentication

Im using this binding
<basicHttpBinding>
<binding name="abc_Windows" maxReceivedMessageSize="2147483647" messageEncoding="Mtom" transferMode="Streamed">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
Im getting this error when calling it.
HTTP request streaming cannot be used in conjunction with HTTP authentication.
Either disable request streaming or specify anonymous HTTP authentication.
Parameter name: bindingElement
Im using windows authentication and need large files to be uploaded and downloaded via this service. What changes should i do to avoid this error? Does any other binding works with streaming and windows mode authentication?
Kindly help.

Can you test a certificate-secured WCF service with SoapUI?

I have a WCF service that is:
Using the BasicHttpBinding (if you can answer for WsHttpBinding even better!)
Using TransportWithMessageCredential Security
Using X.509 Certificates for Transport and Message security
I would like to be able to test this service with SoapUI.
However, when I attempt to do so it appears that SoapUI signs more of the message than WCF expects, leading to this error (detected in the Application log after enabling ServiceModel auditing):
CryptographicException: Unable to resolve the '#id-100' URI in the signature to compute the digest.
Alternatively, when I use a WsHttpBinding I get the exception:
MessageSecurityException: The message received over Transport security has unsigned 'To' header.
Similar issues have been raised before:
WCF rejects messages with additional signed elements
http://connect.microsoft.com/VisualStudio/feedback/details/481030/wcf-signed-parts
Getting WCF to accept unsigned 'To' Header
This does not strike me as a "Java talking to MS WCF" issue - I have a Java test client working without issue. Likewise, I can use WCFStorm to test the service. However, SoapUI has become a bit of a de facto test standard, particularly for non-Windows consumers.
So, has anyone managed to overcome these issues and test a certificate-secured WCF service using SoapUI?
Thanks
I believe this issue is irresolvable, based on my own testing and a 250 bounty not yielding an answer.
The "web.config" is generated dynamically, but it's effectively matching either of the following bindings:
<wsHttpBinding>
<binding name="WSHttpBinding_ITwoWayAsync" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="250000" maxReceivedMessageSize="250000"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Certificate" proxyCredentialType="None" realm="" />
<message clientCredentialType="Certificate" negotiateServiceCredential="false"
establishSecurityContext="false"
algorithmSuite="Default" />
</security>
</binding>
</wsHttpBinding>
<basicHttpBinding>
<binding name="BasicHttpBinding_ITwoWayAsync" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="250000" maxReceivedMessageSize="250000"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Certificate" proxyCredentialType="None" realm="" />
<message clientCredentialType="Certificate" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
This was impossible with SoapUI and I had to use another tool called WCFStorm.
I had exactly the same issue. I haven't it working with BasicHttpBinding but do have it working with WsHttpBinding. I had the error The message received over Transport security has unsigned 'To' header as well. I created a blogpost for solving this issue. Se the blogpost Connect SoapUI to WCF service certificate authentication for more information.
You have to set the parts in the signature. By default SoapUI signs the whole request but that isn’t the default by WCF so we have to set the parts that we want to sign. So add as Name “To”, Namespace “http://www.w3.org/2005/08/addressing” (this is my namespace but check yours) and set Encode to “Element”. Also check the WS-A panel in your request. Check addressing and set the default "To" checkbox.
I have been able to do this with a custom binding in WCF and a PFX certificate file. I had to use a custom binding because I needed to restrict access to one certificate - which is outside the scope of this question. My certificate pfx file had both the public key and the private key. The private key was password protected. I could not get to this work with any other certificate format.
In SoapUI, I go to File -> Preferences -> SSL Settings:
-->Keystore Name: path_to_PFX_file
-->KeyStore password: your_private_key_password
Here are my web.config settings which are pretty much the same as a basicHttpBinding:
<customBinding>
<binding name="MyServiceBindingConfiguration">
<security authenticationMode="UserNameOverTransport" includeTimestamp="false" requireDerivedKeys="false" securityHeaderLayout="Lax" messageProtectionOrder="SignBeforeEncrypt" messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
<localClientSettings maxClockSkew="00:30:00" />
<localServiceSettings maxClockSkew="00:30:00" />
<secureConversationBootstrap />
</security>
<textMessageEncoding messageVersion="Soap11">
<readerQuotas maxDepth="32" maxStringContentLength="524288" maxArrayLength="524288" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</textMessageEncoding>
<httpsTransport requireClientCertificate="true" />
</binding>
</customBinding>
Hope this helps.

When does WCF NetTcpBinding need full trust on the client?

I'm using WCF to communicate to several servers.
For my local server netTcpBinding works like expected, no problems.
But when I try to connect to my remote server (Azure) using the following netTcpBinding in app.config, this will crash the application on initialization since the netTcpBinding can't be created without full trust.
This binding in the app.config file,
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288"
maxBufferSize="65536" maxConnections="10" maxReceivedMessageSize="65536">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Transport">
<transport clientCredentialType="None" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
It will result in this error:
An error occurred creating the configuration section handler for "system.serviceModel/bindings": That assembly does not allow partially trusted callers. (K:\Somepath\Testing.exe.Config line 6)
The strange thing: In the app.config file I got client endpoints connecting to other netTcpBindings (without declaring them explizitely in the binding section).
Why do these generic netTcpBindings work in partial trust, but the one I showed above does not?
Or am I just confused by this error message and the problem is not about full trust?
Update: If I remove the <binding> section the stuff will run without problems. So I'm allowed to use netTcpBinding in partial trust, but I'm not allowed to modify the parameters? This is a pity since I'd like to have some form of encryption on my communication.
NetTcpBinding in general is not supported in partial trust environments.
While the basic communication works fine (as you've seen in other environments), features like TransportSecurity and ReliableMessaging (which you have on your sample configuration) are explicitly not supported on partial trust (it sucks, big time).

WCF Client - only first 255 bytes of stream returned from WCF service contain values

I have been tasked to look after an ASP.Net WebForms application that communicates with a WCF service hosted by a Windows service. The binding used for the service is netTcpBinding.
The service exposes methods to Upload and Download ‘files’. The user select to upload a file and the HttpPostFile.InputSteam is passed directly to the service as a parameter in the service 'Upload' method. The service saves the stream as a byte array to the database [database field data type is varbinary (max)].
The file download data flow is essentially the reverse process. The bytes are retrieved from the database; loaded into a MemoryStream in the WCF service; and then returned to the Web Application.
I have captured the data contained in the streams (sent / received) at each step in the above operations - on the client (web app) and the service. I have looped through and written out to a flat file the bytes contained in each stream.
The byte array in each case is identical [byte value; and number of bytes in the stream] except for the File Download operation. At the point where the stream is returned to the Web Application from the WCF service. Here the number of bytes received is correct but only the first 255 bytes are populated. The values of the remaining bytes are zero
I have made a host of experimental changes to the binding values - in both the client at service - as I believe that the problem must lie here. To date I have not influenced the status of the bytes returned in any way. The logs for the Client and service do not show any that any exceptions are thrown or any other problems.
I do not have much experience in setting the correct combinations of binding (and other configuration) attributes for Client and Server applications – having relied on defaults in the past. We need the service and client to be configured to transfer the maximum allowable file size. Unfortunately I cannot use MTOM.
This post and links, did not offer me any insight. So far I have found no other information that helps.
Hopefully someone can assist me with what the issue might be. Below are the bindings that I am using:
Client [web.config]:
<bindings>
<netTcpBinding>
<binding name="TCP"
closeTimeout="00:01:00"
openTimeout="00:10:00"
receiveTimeout="00:01:00" sendTimeout="00:01:00"
transferMode="Streamed"
maxBufferPoolSize="512"
maxBufferSize="2147483647"
maxConnections="10"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="32"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="4096"
maxNameTableCharCount="2147483647" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
Service:
<netTcpBinding>
<binding name="netTCP"
closeTimeout="00:01:00"
openTimeout="00:01:00"
receiveTimeout="00:01:00" sendTimeout="00:01:00"
transferMode="Streamed"
listenBacklog="30"
maxBufferPoolSize="512"
maxBufferSize="2147483647"
maxConnections="30"
maxReceivedMessageSize="2147483647"
portSharingEnabled="true">
<readerQuotas maxDepth="32"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="4096"
maxNameTableCharCount="2147483647" />
</binding>
</netTcpBinding>
Silly me. I think I have got it.
The bindings were OK. I was not dealing with reading the bytes correctly from the stream into the buffer on the client.