The scenario is WCF service needs to be hosted in IIS with Windows authentication and anonymous login should be disabled. The challenge will be IIS has it authentication mechanism at the same time WCF has its authentication mechanism. The WCF configuration should be done properly to make sure Windows authentication works for a WCF service.
The problem will be complicated when you want access SQL server using windows authentication using WCF service. The document highlights the setting required to configure WCF service Windows authentication which access SQL server with windows authentication.
Problem Statement
Configuring Windows Authentication and disabling anonymous in IIS will not help to know WCF about Windows Authentication. If you disable anonymous authentication you will get the following error when try to access SVC file.
"Security settings for this service require ‘Anonymous’ Authentication but it is not enabled for the IIS application that hosts this service."
Solution
The issue here is WCF configuration and IIS configuration are not in synch. These two sources must be in agreement about whether anonymous access is expected. To configure your web site to use windows authentication update your Web.Config with Windows authentication.
Web Configuration
In Web.Config make sure you set Authentication mode to Windows.
<system.web>
<compilation
targetFramework="4.0"
debug="true"/>
<authentication
mode="Windows"/>
<customErrors
mode="Off"/>
</system.web>
WCF Service Configuration
Binding Configuration
IIS is already using Windows authentication in this case, so let’s look at what needs to happen to the service configuration file. You need to set the security mode to TransportCredentialOnly in service configuration level.
<bindings>
<basicHttpBinding>
<binding
name="winAuthBasicHttpBinding">
<security
mode="TransportCredentialOnly">
<transport
clientCredentialType="Ntlm"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
NTLM / Windows
Transport clientCredentialType can be NTLM / Windows. If you are using Windows Server 2003 make sure you configure your IIS to use NTLM authentication and configure for NTLM otherwise you can use Windows authentication as well.
Make sure the IIS is configured to NTLM by running following script in IIS Box.
Cmd> cscript //nologo c:\Inetpub\AdminScripts\adsutil.vbs GET /W3SVC/1/NTAuthenticationProviders
You must get the following output. If not you can change the above command to SET instead of GET to set NTLM authentication.
Note that TransportCredentialOnly is not supported for every binding (in this case we’re using BasicHttp). For WSHttp, the only choice is going to be to use HTTPS. To switch off anonymous access with HTTPS, you need to set the security mode to Transport.
serviceHostingEnvironment
By default the when you add a service in Web Project it adds aspNetCompatibilityEnabled true. And it adds the attribute the service declaration as well. Make sure you disable this feature. This settings highlighted in this document are based on the assumption that service hosting environment is not set to aspNetCompatibilityEnabled and no aspcompatibility attribute added to the service declaration.
WCF Service Configuration sample
<system.serviceModel>
<serviceHostingEnvironment
multipleSiteBindingsEnabled="true"/>
<bindings>
<basicHttpBinding>
<binding
name="winAuthBasicHttpBinding">
<security
mode="TransportCredentialOnly">
<transport
clientCredentialType="Ntlm"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior
name="" >
<serviceMetadata
httpGetEnabled="true" />
<serviceDebug
includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service
name="YourNamespace.YourServiceName">
<endpoint
address=""
binding="basicHttpBinding"
contract="YourNamespace.YourContractName"
bindingConfiguration="winAuthBasicHttpBinding"
/>
</service>
</services>
</system.serviceModel>
Client Configuration
If you are using Silverlight you need make sure ServiceReferences.ClientConfig is updated to use TransportCredentialOnly.
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding
name="basicHTTP"
maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<security
mode="TransportCredentialOnly" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint
address="http://Server:90/ServiceName.svc"
binding="basicHttpBinding"
contract="YourNamespace.YourContractName"
bindingConfiguration="basicHTTP"
name="BasicHttpBinding_CHEFService" />
</client>
</system.serviceModel>
</configuration>
IIS Settings
Web Site Settings
AppPool Settings
Make sure the AppPool account which you use here has access to SQL Server. Also make sure the account is added to the IIS_WPG