Is there a way to retrieve requested windows username from WCF method - wcf

I am using Custom binding in my WCF services and Proxies. I am creating proxies by inheriting from DuplexClientbase. Is there a option in WCF which helps me to get the username, who invoked the method?
Here is my binding
<bindings>
<customBinding>
<binding name="CustomPipeBinding" maxConnections="10" openTimeout="01:20:00" receiveTimeout="20.00:00:00" sendTimeout="01:20:00" closeTimeout="01:20:00">
<windowsStreamSecurity protectionLevel="None" />
<namedPipeTransport maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
</binding>
<binding name="CustomTcpBinding" maxConnections="10" openTimeout="01:20:00" receiveTimeout="20.00:00:00" sendTimeout="00:05:00" closeTimeout="01:20:00">
<windowsStreamSecurity protectionLevel="None" />
<reliableSession />
<tcpTransport maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"/>
</binding>
</customBinding>
</bindings>

You need to configure your service to require impersonation as outlined in this MSDN article. Since you are defining a custom binding, you'll need to add the required security element config to allow WCF to pass the Windows credentials from the client to the service.
In your service code, you'll need to access the ServiceSecurityContext.Current.WindowsIdentity static property to get what you need.

Related

how to add basicHttpBinding to the custombinding code

I need to authenticate an endpoint using certificate in WCF Config file
I have tried adding with the various authenticationMode setting
but its not working in customBinding
could you please help me to convert the below code to the custom binding
<basicHttpBinding>
<binding name="certBinding">
<security mode="Message">
<message clientCredentialType="Certificate" />
</security>
</binding>
</basicHttpBinding>
This is the code i have tried in custom binding
<customBinding>
<binding name="OutbBinding1" closeTimeout="00:02:00" openTimeout="00:02:00" receiveTimeout="00:10:00" sendTimeout="00:02:00">
<textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16" messageVersion="Soap11" writeEncoding="utf-8">
<readerQuotas maxDepth="32" maxStringContentLength="20000000" maxArrayLength="20000000" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</textMessageEncoding>
<security authenticationMode="SecureConversation">
<secureConversationBootstrap authenticationMode="AnonymousForCertificate" />
</security>
</binding>
</customBinding>
As we know, if we use the message security of BasicHttpbinding, we should set up the certificate both in the client and the server. In addition, we should also establish a certificate trust relationship between the server and the client.
One more thing needs to note is, different from the authentication mode of the transport layer security, we need to set a default service certificate (non-client certificate, use the trusted server certificates for signing messages) on the client side.
So anyway, the below configuration could achieve the same goal that authenticates the client with a certificate. please refer to the below configuration.
<customBinding>
<binding name="TehRealBinding">
<textMessageEncoding />
<security authenticationMode="MutualCertificate" />
<httpTransport />
</binding>
</customBinding>
Besides, the following document might be useful to you.
https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/securitybindingelement-authentication-modes
Feel free to let me know if there is anything I can help you.

Calling WCF service from excel gives error on received message size

I am calling my WCF service from excel VBA code using moniker string. However, as my service returns large data as response, excel gives error message
"Maximum message size quota for incoming messages (65534) has been exceeded. To increase the quota used the MaxReceivedMessageSize property on the appropriate binding element"
Here is the moniker string:
addrToService = "service4:mexAddress=""net.tcp://localhost/MyApp/API/Excel/ExcelAPIService.svc/mexTCP"", "
addrToService = addrToService + "address=""net.tcp://localhost/PruCapWebCMHost/API/Excel/ExcelAPIService.svc"", "
addrToService = addrToService + "contract=""IExcelAPIService"", contractNamespace=""http://Prucap/Services"", "
addrToService = addrToService + "binding=""NetTcpBinding_IExcelAPIService"", bindingNamespace=""http://MyApp/Services"""
To resolve this, I increased the size in my WCF service's web.config file as shown below:
<netTcpBinding>
<binding name="NetTcpBinding_IPublicService" maxBufferPoolSize="8388608" maxBufferSize="8388608" maxReceivedMessageSize="8388608" portSharingEnabled="true">
</binding>
</netTcpBinding>
<basicHttpBinding>
<binding name="BasicHttpBidning_IPublicService" closeTimeout="00:05:00" openTimeout="00:05:00" sendTimeout="00:05:00" receiveTimeout="00:05:00" maxReceivedMessageSize="8388608" />
<binding name="BasicHttpBidning_ISecureService" closeTimeout="00:05:00" openTimeout="00:05:00" sendTimeout="00:05:00" receiveTimeout="00:05:00" maxReceivedMessageSize="8388608" />
</basicHttpBinding>
....
<service name="ExcelAPIService" behaviorConfiguration="PublicServiceTypeBehaviors">
<endpoint address="" bindingNamespace="http://MyApp/Services" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IPublicService" contract="API.Service.ExcelAPI.IExcelAPIService" name="NetTcpBinding_IExcelAPIService" />
<endpoint address="" bindingNamespace="http://MyApp/Services" binding="basicHttpBinding" bindingConfiguration="BasicHttpBidning_IPublicService" contract="API.Service.ExcelAPI.IExcelAPIService" name="BasicHttpBidning_IExcelAPIService" />
<endpoint address="mex" bindingNamespace="http://MyApp/Services" binding="mexHttpBinding" contract="IMetadataExchange" />
<endpoint address="mexTCP" bindingNamespace="http://MyApp/Services" binding="mexTcpBinding" bindingConfiguration="" contract="IMetadataExchange" />
</service>
According to various forums on this topic, the above solution should work. But this does not work in my case when called from excel. Is there anything I need to do from excel side to set the maxReceivedMessageSize? If yes then how can I do this using VBA code?
Additional information:
I use Office 2010 (with VBA), Windows 7 Prof, 64bit OS
The maximum size must be set by the client as well as the server. However, the service moniker form you are using does not support specifying this parameter.
From first hand experience I can tell you, using monikers may seem appealing at first, since it allows you to call services from VBA with minimal coding, but it is very limited in what it can do. I discovered, as no doubt you are in the process of dicovering as well, the best way to approach this is to build a proper WCF client - probably in .NET - and call the client class from your VBA, or even Excel directly.
If you are trying that and are still having trouble, please start a new thread so you can post your code, and more fully explain what you have tried, and what the problem is.
You should set maxReceivedMessageSize="2147483647" to increase message size.
Try increasing message size like:
<binding maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
</binding>
--OR
<basicHttpBinding>
<binding name="BasicHttpBinding_IManagementService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="2147483647" maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="128" maxStringContentLength="2147483647"
maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
refer WCF Error "Maximum number of items that can be serialized or deserialized in an object graph is '65536'"
Wcf-The maximum message size quota for incoming messages (65536) has been exceeded?
UPDATE
You also can change endpoint/service behavior programatically.
Refer links:
How to: Specify a Service Binding in Code
How to: Programmatically Configure a WCF Endpoint
Update2:
Sorry Anil, Previously I totally overlook you are doing this in excel.
The easiest way for your scenario to use WCF service from VB6 is to create a .Net ComObject wrapper for the service client. Then in VB6 all your are doing is a create object and calling some methods on the object. All the WCF work takes place in the .Net com object.
Simply create the WCF client to the service in a separate project as described in this link. Register the .NET assembly as a type library which you would then link from the VB6 app : link.
Sources:
Using WCF in VB6
Integrating WCF Services with COM+
Communicate with WCF Windows Service in VB6?
Hope it helps. :)

Calling a webservice from a C# dll from within CLASSIC ASP

I'm a windows dev with very little knowledge of web applications and ASP. I'm trying to create a C# dll (which is making a webservice call) for someone, that is being called from a CLASSIC ASP app.
It all started from a WinForms test app that successfully loaded a WSDL and called that web service. Now the requirement is to take the test app functionality, move it to a dll and call that dll from the ASP app. I naively left the appconfig file there, and when that dll was called, he got this well known error:
Could not find default endpoint element that references contract Service1.MyService in the
ServiceModel client configuration section. This might be because no configuration file was found
for your application, or because no endpoint element matching this contract could be found in the
client element.
I understand that classic asp doesn't have config files - I read a lot of posts about it, and most of the relevant ones mention to use BasicHTTPBinding and provide an endpoint address on the fly. How do I do that? Any examples?
I saw this answer:
All I needed to do is to create a BasicHTTPBinding and provide an endpoint address on the fly.Then create a new instance of the web service using the created binding and endpoint address.
But i'm not sure how to do it.
This is the appconfig that worked for the winforms app:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IMyService">
<security mode="Transport">
<transport clientCredentialType="Certificate" proxyCredentialType="None"
realm="" />
</security>
</binding>
<binding name="BasicHttpBinding_ICustomerService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://MyService.svc"
behaviorConfiguration="custom" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IMyService" contract="MyService.IMyService"
name="BasicHttpBinding_IMyService" />
</client>
<behaviors>
<endpointBehaviors>
<behavior name="custom">
<customInspector />
</behavior>
</endpointBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="customInspector" type="CustomBehaviors.CustomBehaviorExtensionElement, CompeteDataServiceTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</behaviorExtensions>
</extensions>
</system.serviceModel>
You will need to configure the service through code, as there is no config file in this case. See Configuring WCF Services in Code.

WCF: Is it possible to specify default client configuration settings in the service's Web.config?

Is it possible to define default client binding configurations in the service's Web.config file?
I would like to specify default maxReceivedMessageSize and maxBufferPoolSize values so that clients don't need to constantly change the defaults
Something along the lines of this (which doesn't work):
<bindings>
<wsHttpBinding >
<binding name="Standard" maxReceivedMessageSize="6000000" maxBufferPoolSize="200000000" >
<readerQuotas maxDepth="32" maxBytesPerRead="200000000"
maxArrayLength="200000000"
maxStringContentLength="200000000"/>
<security mode="TransportWithMessageCredential" />
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint binding="wsHttpBinding"
bindingConfiguration="Standard"
contract="SomeContract" />
</client>
In WCF 4 (.NET 4) - yes: just leave the name= attribute blank (or omit the name= attribute all together) - so use
<bindings>
<wsHttpBinding >
<binding
maxReceivedMessageSize="6000000" maxBufferPoolSize="200000000" >
<readerQuotas maxDepth="32" maxBytesPerRead="200000000"
maxArrayLength="200000000" maxStringContentLength="200000000"/>
<security mode="TransportWithMessageCredential" />
</binding>
</wsHttpBinding>
</bindings>
and then those settings apply to all wsHttpBinding's used by endpoints in that configuration file.
Read more about what's new in WCF 4 here: A Developer's Introduction to WCF 4 - the default binding and behavior configuration is listed there, too (not too far from the top).

WCF Client consuming multiple services

I'm trying to figure out how to set up my web.config (the client) to consume two different WCF web services one using the other using
I have the two endpoint, I guess I need two different Binding configurations. This is my current binding node:
<basicHttpBinding>
<binding name="WebServiceProxyServiceSoapBinding" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:01:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="2147483647" maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
I can't add another basicHttpBinding node. The thing is if ALL I changed was the mode parameter in <security mode="Transport"> then the binding will work great for one or the other endpoint.
This seems like a common issue, but have not found an answer. Overall I'm not very experiences with WCF (if that is not obvious) outside the simple consume and call. Any help would be GREAT!
This article was close but not quite the same issue as they did not need a different security mode.:
How to consume multiple WCF services from one client
Thanks in advance.
You just need to add another <binding> node, with a different name and whatever different options you like, under the <basicHttpBinding> node.
Then, obviously, just make sure each client is configured to use the binding that's specific to them by setting the appropriate name in the bindingConfiguration attribute for each <endpoint> node.
I have the two endpoint, I guess I
need two different Binding
configurations. This is my current
binding node:
Not necessarily - if these two services use the same settings and same protocols, one binding configuration will do.
What you need to add two of is a client element:
<system.serviceModel>
<bindings>
..... (as you already have it) ....
</bindings>
<client>
<endpoint name="Service1Endpoint"
address="http://yourserver/service1.svc"
binding="basicHttpBinding"
bindingConfiguration="WebServiceProxyServiceSoapBinding"
contract="IWCFService1" />
<endpoint name="Service2Endpoint"
address="http://yourserver/service2.svc"
binding="basicHttpBinding"
bindingConfiguration="WebServiceProxyServiceSoapBinding"
contract="IWCFService2" />
</client>
</system.serviceModel>
That should do.
Of course, if your second service uses another binding, or needs different security settings, then yes, you'd need to add a second <binding name="something else" .....> under your <basicHttpBinding> node and reference that second binding configuration from one of your two client endpoints here.