Configuring WCF to do anything for the first time is very time consuming, frustrating and just generally a hassle. My coworker and I mucked through this wonderful WCF configuration experience last night and now I am going to share our tale of torment and learning.
Useless and Unhelpful Errors
If you have been having trouble setting this up, then chances are you have seen one of two or both of these page errors that are served to you on a steaming hot yellow screen of death:
Useless Error 1
Security settings for this service require Windows Authentication but it is not enabled for the IIS application that hosts this service.
Security settings for this service require ‘Anonymous’ Authentication but it is not enabled for the IIS application that hosts this service.
- Open IIS manager > Click on your Application > Make sure Features View is selected
- In the IIS section of Features View double click on “Authentication” (Figure 1)
- Enable Anonymous Authentication (Figure 2)
- Enable Windows Authentication (Figure 2)
- On the left hand side of the window look at the Actions section.
- Click on “Advanced Settings…” make sure Extended Protection is “OFF” and check mark the check box labeled “Enable Kernel-mode authentication” (checked=”True”)**. (Figure 3)
- Click on “Providers…” and make sure the Enabled Providers are only “Negotiate” and “NTLM”, do not add anything else here. (Figure 4)
- Restart IIS using CMD > iisreset /restart
- You are finished with configuring IIS, time to configure WCF.
- Enabling Windows Authentication for the Web Application
- Enabling Windows Authentication for the WCF Service
Put the following authentication section into the <system.web> section. In this example I am using Active Directory group names to filter out who has access. You can use the user names directly if you want.
<authentication mode="Windows" /> <authorization> <allow roles="ADGroup1,ADGroup2" /> <deny users="*" /> </authorization> <identity impersonate="false" />
Put the following secruity section into your <binding> section.
<security mode="TransportCredentialOnly"> <transport clientCredentialType="Windows" /> </security>
Full Web.Config Example For Reference
<?xml version="1.0"?> <configuration> <system.web> <compilation debug="true" targetFramework="4.0"> </compilation> <httpRuntime executionTimeout="600" maxRequestLength="16384" /> <authentication mode="Windows" /> <authorization> <allow roles="ADGroup1,ADGroup2" /> <deny users="*" /> </authorization> <identity impersonate="false" /> </system.web> <system.serviceModel> <services> <service name="AuthWCFService.AuthService" behaviorConfiguration="AuthWCFService.AuthServiceBehavior"> <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpBindingConfig" contract="AuthWCFService.IAuthService" /> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services> <bindings> <basicHttpBinding> <binding name="basicHttpBindingConfig" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" closeTimeout="00:10:00" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" messageEncoding="Text" transferMode="Buffered" > <security mode="TransportCredentialOnly"> <transport clientCredentialType="Windows"/> </security> <readerQuotas maxDepth="32" maxStringContentLength="20000000" maxArrayLength="20000000" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> </binding> </basicHttpBinding> </bindings> <behaviors> <serviceBehaviors> <behavior name="AuthWCFService.AuthServiceBehavior"> <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --> <serviceMetadata httpGetEnabled="True" /> <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> <serviceDebug includeExceptionDetailInFaults="true" /> </behavior> </serviceBehaviors> </behaviors> <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> </system.serviceModel> </configuration>
I think Microsoft needs to make this easier to figure out… Why the configuration has to be such a mystery that requires countless hours of plug and chug is beyond me. I have tried reading the white papers that are provided, but they are as useful as college books or technical manuals when you aren’t really sure where to begin. As I like to call it FLUFF, lots and lots of FLUFF – no practicality – just lots of meaningless words strung into sentences.