WCF + IIS6 + HTTPS + Basic authentication - wcf

I have seen loads of questions about this, I've spent over a day researching and trying to fix it but I've drawn a blank.
I want to deploy a WCF service onto a server connecting with HTTPS and using basic authentication. Here is my service web.config
I am using an extremely simple Calculator as a test which has a single method which adds together two numbers.
<configuration>
<system.web>
<compilation debug="false" targetFramework="4.0" />
<customErrors mode="Off" />
</system.web>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="UsernameWithTransport">
<security mode="Transport">
<transport clientCredentialType="Basic" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="Service">
<endpoint address="https://myserver.mydomain.co.uk/CalculatorService"
binding="wsHttpBinding"
bindingConfiguration="UsernameWithTransport"
name="BasicEndpoint"
contract="TestCalculator" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
In IIS 6.0 I have enabled basic authentication and required HTTPS.
I can browse to the .svc file and it asks for my credentials. I provide them and it displays the default page. However it says:
You have created a service.
To test this service, you will need to create a client and use it to
call the service. You can do this using the svcutil.exe tool from the
command line with the following syntax:
svcutil.exe
http://myserver.mydomain.co.uk/CalculatorService/Service.svc?wsdl
This will generate a configuration file and a code file that contains
the client class. Add the two files to your client application and use
the generated client class to call the Service. For example: ......
Basically, the issue seems to be that the path to the .wsdl is a http:// not an https:// and I don't think I understand why.
I am now trying to create a C# console application to test consuming the service. I cannot add the reference to the .svc path directly because it just goes around and around in a loop asking me for my username and password. If I add the reference to the .svc?wsdl then that did work but then invoking the service gives a "Method not allowed" because it is trying to use HTTP not HTTPS.
Hope I have expained this well enough. Thanks for any help.

You requires HTTPS but in the same time you allow WSDL only over HTTP. Change this:
<serviceMetadata httpGetEnabled="true"/>
To this:
<serviceMetadata httpsGetEnabled="true"/>
Now you will be able to access WSDL over https://..../....svc?wsdl but you will still have to authenticate because authentication is global for your deployed site.

Related

mvc wcf security

I have a MVC application which uses forms authentication. This application also hosts a WCF webservice (the Model). Webservice caters c# objects to the application, and same data is available as JSON when called from outside the application (browser).
Everything is working fine apart from the fact that the Webservice is not authenticating any request. Following is the what I have in web.config:
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<behaviors>
<endpointBehaviors>
<behavior name="ServiceBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="webHttpBindingWithJson" crossDomainScriptAccessEnabled="true" />
</webHttpBinding>
</bindings>
<services>
<service name="Services.MyService">
<endpoint address="http://localhost:1234/MyService.svc/" binding="webHttpBinding"
bindingConfiguration="webHttpBindingWithJson"
contract="Services.IService"
behaviorConfiguration="ServiceBehavior"/>
</service>
</services>
I would like to authenticate Webservice requests:
Requests from within the application should be authenticated automatically
When Webservice is called from outside the application, users are asked to get authenticated.
Any help would be appreciated.
/D
Sounds like you need an internal endpoint that serves a wsdl for the binding in to the website (authenticated using the ASP.NET identity the website is running under) and a separate binding externally for the JSON requests that uses something like OAuth to authenticate.
Either way you're looking at two different authentication mechanisms.

"The caller was not authenticated by the service" when using a customBinding only on machines on a domain

I wrote a WCF service hosted by IIS 6 on a server that is not part of a domain. It uses the following configuration:
<system.serviceModel>
<services>
<service behaviorConfiguration="ServiceBehavior" name="Services.DeliveryStatsService">
<endpoint address="" binding="customBinding" bindingConfiguration="BindingWithMaxClockSkewForIncorrectlyConfiguredWindowsServer"
contract="Services.IDeliveryStatsService" />
</service>
</services>
<bindings>
<customBinding>
<binding name="BindingWithMaxClockSkewForIncorrectlyConfiguredWindowsServer">
<binaryMessageEncoding />
<security>
<localClientSettings maxClockSkew="00:20:00" />
<localServiceSettings maxClockSkew="00:20:00" />
<secureConversationBootstrap />
</security>
<httpTransport />
</binding>
</customBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
It would've been a simple basicHttpBinding, except that the server's clock is not set to the right time and its administrator will not change that, so a customBinding is required to allow for "clockSkew."
Clients use pretty much the same configuration (binding-wise) and can access the service without any trouble, as long as they are not part of a domain. However, clients that are part of a domain are rejected with the message "The caller was not authenticated by the service."
I turned on tracing and it would seem that the problem comes from a token exchange using SSPI negociation. Unfortunately, I can't seem to find the right configuration that will allow both machines that are not part of a domain and machines that are part of a domain to access the service. I have tried several values for authenticationMode, without avail. What's more, as far as I'm concerned, I don't need any particular security on this service.
WCF configuration is far from being my specialty and I haven't found an answer anywhere else, so I hope someone at Stack Overflow will be able to help. Thanks in advance.
Why do you need to set maxClockSkew when you don't need security? It is for handling time differences in timestamps which are not send without security. Once you add security element you turn on authentication because all attributes in the element have default values. Default value for mode is sspiNegotiated. I would start with removing security element.

Wcf Http and Https

Help please!!
I had the following set up working perfectly:-
WCF Service Library hosted in web site on local IIS 7
Silverlight Application on a web site on local IIS 7 using above services
The solution I am writing is for intranet and not internet use, however I have been told by my bosses that it needs to be over Https. I am using Windows Authentication.
Below is a chunk of the config file for one of the service endpoints (changed to remove company info etc):-
<services>
<service behaviorConfiguration="stdHttpBehavior" name="WcfServiceLibrary.StaticDataService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="windowsHttpBinding"
name="StaticDataService" contract="WcfServiceLibrary.ServiceContracts.IStaticDataService" />
<endpoint address="mex" binding="mexHttpBinding" name="" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost/WcfServiceLibrary/StaticDataService/" />
</baseAddresses>
</host>
</service>
<behaviors>
<serviceBehaviors>
<behavior name="stdHttpBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
</serviceBehaviors>
</behaviors>
To experiment with Https I created a 'Self-Signed Certificate'. I then added https to the Default Web Site bindings and changed the two web sites to require SSL and also changed the relvant URIs in the config files. I managed to get this to work but now I want to go back to standard Http and finish the project in that mode as it was easier to work with. I changed all the settings back (and I have checked these extremely carefully).
Now I get this error if I try to downoad the Service definition in the Silverlight project: -
'Could not find a base address that matches scheme https for the endpoint with binding BasicHttpBinding. Registered base address schemes are [http].'
If I put back the certificate and binding in IIS. The Service definition appears to download OK, however it references an https URI and therefore none of the actual service calls work as they are http adresses!
I tried adding a new web site to host the service but got the same errors.
I have been trying to solve this for the last couple of days but cannot find an answer. It seems as though there is a hidden reference somewhere and not in my project as it continued with a new web site added to IIS.
To use SSL over HTTP under Basic HTTP binding, you need to switch your endpoint to use Transport-level security. In your case you will also want to indicate the client credential type:
<bindings>
<basicHttpBinding>
<binding name="windowsHttpBinding">
<security mode="Transport">
<transport clientCredentialType="Windows" />
<message />
</security>
</binding>
</basicHttpBinding>
</bindings>
It may seem obvious, but did you change the security mode on the windowsHttpBinding binding configuration to BasicHttpSecurityMode.None?
<bindings>
<basicHttpBinding>
<binding name="windowsHttpBinding">
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
Related resources:
Transport Security Overview
BasicHttpSecurityMode Enumeration

Integrated Windows Authentication WCF Multiple Host Headers IIS 6 not working

I have a asp.net 2.0 web site with WCF service hosted inside it running on .NET 3.5 framework. The website is setup with Integrated Windows Authentication only. The web server is IIS 6 with load balancing on Windows 2003 Sp2 (2 servers). I am unable to access the WCF service (.svc) using the full url (http://myqa2.abcdefg.com/trxn/WCFTrxnService.svc). Also note that the server is configured with multiple host headers. The website is protected by siteminder. Initially I was getting an error
This collection already contains an address with scheme http. There can be at most one address per scheme in this collection. Parameter name: item
So added the following config entry
<serviceHostingEnvironment>
<baseAddressPrefixFilters>
<clear/>
<add prefix="http://myqa2.abcdefg.com"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
That error went away, but now I am being prompted for login by the browser. For same website, I am able to access .aspx page. The login prompt is appearing only for .svc file.
Here is the binding / endpoint from config file that I am using.
<system.serviceModel>
<serviceHostingEnvironment>
<baseAddressPrefixFilters>
<clear/>
<add prefix="http://myqa2.abcdefg.com"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
<bindings>
<basicHttpBinding>
<binding name="IISIntegratedAuthBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="TestWCFFromSL.Web.WCFTrxnServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://myqa2.abcdefg.com/fmc/WCFNotesService.svc"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="TestWCFFromSL.Web.WCFTrxnService" behaviorConfiguration="TestWCFFromSL.Web.WCFTrxnServiceBehavior">
<endpoint
address="http://myqa2.abcdefg.com/trxn/WCFTrxnService.svc"
binding="basicHttpBinding"
bindingConfiguration="IISIntegratedAuthBinding"
contract="TestWCFFromSL.Web.IWCFTrxnService" />
</service>
</services>
<!--<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>-->
if a website is protected by SiteMinder, WCF / SOAP calls don't work. But a different solution to this problem is working.
The URL myqa2.abcdefg.com/trxn/WCFTrxnService.svc is protected by SiteMinder, but
myqa2/trxn/WCFTrxnService.svc is not protected by siteminder, Looks like SiteMinder only protects FQDN (Fully Qualified Domain Names). So I configured the application to call WCF service using short url instead FQDN. I also had to use crossdomainpolicy because the application considers myqa2.abcdefg.com and myqa2 as 2 seperate domains.

WCF Over SSL Uses Machine Name IIS 7.5

I am having trouble setting up SSL with my WCF on IIS 7.5. I have seen this post:
WCF not using computer name instead of domain name when viewing MyService.svc?wsdl
However, the solution for IIS 7 does not seem to be working for me. In addition, I have a wildcard ssl, I'm not sure if that makes a difference.
I have tried modifying the applicationHost.config to both:
<bindings>
<binding protocol="https" bindingInformation="<ip or *>:443:<my.domain.com>" />
</bindings>
and
<bindings>
<binding protocol="https" bindingInformation="<ip or *>:443:<mycname>" />
</bindings>
IIS Resets seem to have no impact.
Little help anyone?
Going to answer my own question. The correct way to fix this is to adjust the web config on your WCF to include httpsGetEnabled="true". The relevant portion should look like this:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpsGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
After making this adjustment, you will need to delete, and re-add your web reference. I rebuilt the project, but I am not sure if that is necessary.