How to enable both HTTP and HTTPS for AJAX-enabled WCF service? - ajax

Here is my config settings, which currently only allows HTTP:
<system.serviceModel>
<services>
<service name="MyAjaxSvc">
<endpoint address="" behaviorConfiguration="MyAjaxSvcEndpointBehavior"
binding="webHttpBinding"
contract="MyAjaxSvc" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="MyAjaxSvcEndpointBehavior">
<enableWebScript />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
This service could potentially be called on any page on my website. Some pages are HTTPS, so I would like to set it up so that the service can be called (AJAX) using either protocol. Ideally, I would like all my AJAX service calls to be HTTPS, but since you can't mix protocols, I will settle for allowing the service to be called using what ever protocol the current page is using.

Shot in the dark:
You'll need to add another Binding (declared above the code you show (normally)), and then declare another endpoint.

Related

How to fix: "Metadata contains a reference that cannot be resolved:'http://<host>:<port><path>?wsdl'." for "Configure WCF Web Service Reference" in vs

I have been trying to publish a WCF web service on my IIS server using a nonstandard HTTPS port. Access to the server should only be possible after authentication (via basic authentication). The web service I created for testing purposes is the base project you get by default when creating a WCF Service Application in Visual Studio. The only modifications I made are in the web.config file:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.6.1" />
<httpRuntime targetFramework="4.6.1"/>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<bindings>
<basicHttpBinding>
<binding name="secureHttpBinding">
<security mode="Transport">
<transport clientCredentialType="Basic"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="SoapApi.Service1">
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="secureHttpBinding"
contract="SoapApi.IService1"/>
<endpoint address="mex"
binding="mexHttpsBinding"
contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
After the service was published on the local file system and the IIS was configured. I was able to reach the WSDL file on the server after authentication from the browser on my local PC. But if I'm trying to add the service to a simple client application using the Configure WCF Web Service Reference wizard from Visual Studio, I get the following error message:
Metadata contains a reference that cannot be resolved:'http://<host>:<port><path>?wsdl'.
and the full error message:
An error occurred while attempting to find services at 'http://<host>:<port><path>?wsdl'. The remote server returned an error: (403) Forbidden.
Since this error indicates that I don't have access permission, I thought why not turn off authentication and try if it works. I activated anonymous access for the website in IIS and deactivated basic authentication.
Furthermore I changed the following passage in the web.config file:
<basicHttpBinding>
<binding name="secureHttpBinding">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
I can still access the WSDL file from my browser, but nevertheless I still get the same error when adding the service reference to the client. The same happens if I test it via dotnet-svcutil http://<host>:<port><path>?wsdl
If I try to add the service reference locally everything works without any issues.
Additional information:
I already installed .NET Framework 4.6 and it's WCF HTTP Activation handler.
I added the permission IIS_IUSRS to the folder containing the service.
Any ideas to why this happens and what I could do to fix this problem?
If you use transport security mode, why not use https addresses? The https/http base address should be configured in IIS site binding module.
In addition, since you are using basic authentication, please turn on anonymous authentication and basic authentication in the IIS authentication module.
On my side, I can add service references correctly using the Core-based console application.
Besides, Please enable the following windows feature for WCF.
Feel free to let me know if there is anything I can help with.

WCF data serialization performance issue

I have a WCF based client service application. I'm using EF to interact with mysql db. I'm using my own entities for data transferring between client and server. Here is my binding schema:
<system.serviceModel>
<services>
<service name="...BusinessService" behaviorConfiguration="SimpleServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="net.tcp://127.0.0.1:8001/....BusinessService/"/>
</baseAddresses>
</host>
<endpoint address="CommonService" binding="netTcpBinding" bindingConfiguration="NetTCPBindingCommon" contract="....ICommonService"/>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="NetTCPBindingCommon" closeTimeout="00:11:00" openTimeout="00:11:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00"
maxBufferSize="65536000" maxBufferPoolSize="52428800" maxReceivedMessageSize="65536000"
hostNameComparisonMode="StrongWildcard" transferMode="Buffered" transactionFlow="false"
transactionProtocol="OleTransactions">
<readerQuotas maxDepth="32" maxStringContentLength="81920000" maxArrayLength="16384000"
maxBytesPerRead="4096" maxNameTableCharCount="1638400"/>
</binding>
.......
The data serialization and deserialization during client service data transfering is very slow. How can I make it more faster?
What is today's best solution for performance issue?
Is Json.NET the best solution as I found on some forums?

App.Config for Federated Security with client certificate in Thinktecture IdentityServer

Currently I can establish a WCF channel with an IssuedToken by first establishing the security token from the STS with a certificate credential via the WS-Trust endpoint and then calling CreateChannelWithIssuedToken() on the channel factory. See How to specify a certificate as the credentials for a wsTrustChannel with Thinktecture IdentityServer
However, instead of doing this:
var securityToken = GetMeASecurityTokenFromTheSts();
var myServiceChannelFactory = new ChannelFactory<IMyService>();
myServiceChannelFactory.CreateChannelWithIssuedToken(securityToken);
I'd ideally like to just do this (and have the issuer of the security token automatically issue a token based on the passed certificate).
var myClient = new MyServiceClient();
My question is - can a binding be configured something like the following to specify that the ThinkTecture IdentityServer STS is the Issuer for security tokens?
<bindings>
<ws2007FederationHttpBinding>
<binding name="WS2007FederationHttpBinding">
<security mode="TransportWithMessageCredential">
<message issuedKeyType="BearerKey" issuedTokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0">
<issuer address="https://mymachine/myidserver/issue/wstrust/mixed/certificate">
<identity>
<certificateReference storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" findValue="XXXXXXXXXXXXXXXXXXXXXXXXX"/>
</identity>
</issuer>
<issuerMetadata address="https://mymachine/myidserver/FederationMetadata/2007-06/FederationMetadata.xml" />
<tokenRequestParameters>
<trust:SecondaryParameters xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
<trust:TokenType xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0</trust:TokenType>
<trust:KeyType xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer</trust:KeyType>
<trust:Claims Dialect="http://schemas.xmlsoap.org/ws/2005/05/identity"
xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
<wsid:ClaimType Uri="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
xmlns:wsid="http://schemas.xmlsoap.org/ws/2005/05/identity" />
</trust:Claims>
<trust:CanonicalizationAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/10/xml-exc-c14n#</trust:CanonicalizationAlgorithm>
<trust:EncryptionAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/04/xmlenc#aes256-cbc</trust:EncryptionAlgorithm>
</trust:SecondaryParameters>
</tokenRequestParameters>
</message>
</security>
</binding>
</ws2007FederationHttpBinding>
</bindings>
if so - I'm having a lot of trouble configuring this part of the binding:
<issuer address="https://mymachine/myidserver/issue/wstrust/mixed/certificate">
<identity>
<certificateReference storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" findValue="XXXXXXXXXXXXXXXXXXXXXXXXX"/>
</identity>
</issuer>
My main area of confusion is this: The issuer config element seems to encapsulate the binding, behavior and endpoint all in one element. The binding can be configured - and clearly has to as the above issuer element complains about not having a binding configured. But how do you specify the SSL certificate for the issuer channel as this is a behavior configuration thing, and there doesn't appear to be any way to set the behavior for the issuer endpoint.
Using the config only approach has indeed the problem of binding the token lifetime to the proxy lifetime. In addition the realm (appliesTo) you configure in IdentityServer has to match the physical URL of the WCF service. Both is IMO not practical and the "manual" WSTrustChannelFactory approach is much more recommended.
That said - svcutil (or "Add Service Reference") creates all the necessary client configuration for you. You just need to make sure that you point to IdentityServer's MEX endpoint in the WCF service configuration, e.g.:
<bindings>
<ws2007FederationHttpBinding>
<binding>
<security mode="TransportWithMessageCredential">
<message establishSecurityContext="false"
issuedKeyType="BearerKey">
<issuerMetadata address="https://identity.thinktecture.com/idsrvsample/issue/wstrust/mex" />
</message>
</security>
</binding>
</ws2007FederationHttpBinding>
</bindings>
https://github.com/thinktecture/Thinktecture.IdentityServer.v2/blob/master/samples/MVC%20and%20WCF%20RP%20(SAML)/Web/Web.config
...and the MEF issue is fixed btw.
You can set binding configuration for issuer. Use of certificate will be set on MyServiceClient behaviour. I have not tested this configuration but it could work.
Here is your modified configuration
<bindings>
<ws2007FederationHttpBinding>
<binding name="WS2007FederationHttpBinding">
<security mode="TransportWithMessageCredential">
<message issuedKeyType="BearerKey" issuedTokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0">
<issuer address="https://mymachine/myidserver/issue/wstrust/mixed/certificate" binding="ws2007HttpBinding"
bindingConfiguration="issuerBindingConfig">
</issuer>
<issuerMetadata address="https://mymachine/myidserver/FederationMetadata/2007-06/FederationMetadata.xml" />
<tokenRequestParameters>
<trust:SecondaryParameters xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
<trust:TokenType xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0</trust:TokenType>
<trust:KeyType xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer</trust:KeyType>
<trust:Claims Dialect="http://schemas.xmlsoap.org/ws/2005/05/identity"
xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
<wsid:ClaimType Uri="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
xmlns:wsid="http://schemas.xmlsoap.org/ws/2005/05/identity" />
</trust:Claims>
<trust:CanonicalizationAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/10/xml-exc-c14n#</trust:CanonicalizationAlgorithm>
<trust:EncryptionAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/04/xmlenc#aes256-cbc</trust:EncryptionAlgorithm>
</trust:SecondaryParameters>
</tokenRequestParameters>
</message>
</security>
</binding>
</ws2007FederationHttpBinding>
<ws2007HttpBinding>
<!--SWACA RAWS Client authentication binding-->
<binding name="issuerBindingConfig">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="Certificate" establishSecurityContext="false" />
</security>
</binding>
</ws2007HttpBinding>
</bindings>
<endpointBehaviors>
<behavior name="MyServiceClient">
<clientCredentials supportInteractive="false">
<clientCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" findValue="XXXXXXXXXXXXXXXXXXXXXXXXX" />
</clientCredentials>
</behavior>
</endpointBehaviors>
However please keep in mind that if you do that then each new MyServiceClient() will practically request a token from STS. When we used this approach in our system we had some MEF threadsafety problems with IdentityServer.

Debugging problem for a Role instance with Azure Compute Emulator,Server Error in '/' Application

I create a new service of notification for a webRole
I defined the service in web.config
<system.serviceModel><services>
<!-- Notification Service Definition -->
<service behaviorConfiguration="NotificationServiceBehaviors" name="Paw.Services.NotificationService">
<endpoint binding="basicHttpBinding" contract="Paw.Services.INotificationService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="NotificationServiceBehaviors">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors></system.serviceModel>
But when i try to debug and start a new instance of a webrole, the service deploys in ASP.net Server not in Compute Emulator.
I don't know why it is acting like this and the web.config isn't used at all in starting the new instance.
Could it be as simple as not selecting the cloud project as the Start Project in Visual Studio?

Silverlight and WCF with Windows Authentication

I have a Silverlight application in an ASP.NET web application. I then have a WCF Service Library hosted in an ASP.NET application. I have set up security as TransportWithCredentialOnly and Windows authentication. This is an Intranet scenario.
In IIS7 on a test server I have Anonymous Authentication disabled and Windows Authentication enabled. With this set up the WCF calls fail.
If I enable Anonymous Authentication then it works. What is the point of Windows Authentication if Anonymous Authentication cannot be disabled.
When I used Web Helper in IE it seemed that there was a call to the service similar to when you get the service definition and this need the Anonymous Authentication. I presume then that the actual calls to the Service methods will still be authenticated correctly.
Can anyone please shed some light on this as I am confused. We will be having penetration testers in a few months and I fear that they will not like the idea that they can see the service call in Fiddler or similar which they can then copy and paste into the address bar to get the service definition. Having worked with them before they are very particular and any information they can get from an app is a minus mark. In my particular industry security is extremely important.
If I am doing this wrong any help would be greatly appreciated.
I already struggled with the same problem. I fixed my problem by modifying my web.config file . Here is what I have below.
I hope that will help you!
Good luck.
<system.serviceModel>
<bindings>
<customBinding>
<binding name="MyAp.Web.Services.MyAppSvc.customBinding0">
<binaryMessageEncoding>
<readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647" />
</binaryMessageEncoding>
<httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" authenticationScheme="Ntlm" unsafeConnectionNtlmAuthentication="true" />
</binding>
</customBinding>
</bindings>
<services>
<service name="MyApp.Web.Services.MyAppSvc">
<endpoint address="" binding="customBinding" bindingConfiguration="MyApp.Web.Services.MyAppSvc.customBinding0" contract="MyApp.Web.Services.MyAppSvc" />
<!--<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>-->
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>

Resources