In Part 1 of my WCF and Kerberos delegation post I showed you the basic components of my demo and explained how to do basic configurations for SharePoint to allow Kerberos authentication. I will focus in this second part on how to develop configuration files for the client and the web service. I will also explain the steps required for configuring IIS and Active Directory.

Configuring the Web Service for Kerberos Authentication

Configuring a WCF web service requires a couple of settings in Active Directory, Internet Information Services (IIS) and the web.config file.

Setting the AppPool Service User SPN

  1. Open Active Directory Users & Computers on your domain controller.
  2. Select the service user running the AppPool (created in Part 1) and open the Properties window.
  3. Switch to the Attribute Editor tab (only visible if Advanced Features are selected) and add the following SPN values:       
    12
    Note:
    After creating the SPN values verify that there aren’t any duplicate SPNs by running the following command from the command prompt: setspn –x

Web.config

Choosing the correct settings in the web.config is definitely the most important part of this demo.

Key aspects of the config file are:

  • use wsHttpBinding
  • set the proper security settings for the wsHttpBinding
  • define the service principal name for the endpoint
  • configure an endpoint behavior and force Kerberos by setting allowNtlm=false
  • also choose Delegation as the allowed impersonation level

Web.config

<?xml version="1.0"?>
<configuration>
<configSections>
</configSections>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
<customErrors mode="Off" />
</system.web>
<system.serviceModel>
<client>
<endpoint address="http://green.colors.selfhost.corp.microsoft.com/Hello/HelloService.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IHelloContract"
contract="KRBServer.IKrbService1" name="WSHttpBinding_IHelloContract" behaviorConfiguration="NoNTLM">
</endpoint>
</client>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceTypeBehaviors" >
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="NoNTLM">
<clientCredentials>
<windows allowNtlm="false" allowedImpersonationLevel="Delegation" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="KerberosBinding">
<security>
<message negotiateServiceCredential="true" establishSecurityContext="false" />
</security>
</binding>
<binding name="WSHttpBinding_IHelloContract">
<security>
<message negotiateServiceCredential="true" establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="KRBServer.KrbService1" behaviorConfiguration="MyServiceTypeBehaviors">
<endpoint address=""
binding="wsHttpBinding" bindingConfiguration="KerberosBinding" contract="KRBServer.IKrbService1">
<identity>
<servicePrincipalName value="HTTP/red.colors.selfhost.corp.microsoft.com" />
</identity>
</endpoint>
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>

 

Deploying the Web Service

I use Web Deploy (visit http://msdn.microsoft.com/en-us/library/dd465337.aspx for more details) and the following settings to publish the web service directly from Visual Studio.

9

After the deployment you will need to change the AppPool so that it runs under the service user which has been created in Part 1.

  1. Open the Internet Information Services (IIS) Manager (RED).
  2. Select the deployed application and choose Basic Settings… from the Actions pane.
  3. Change the AppPool – the AppPool needs to be running under the service account which has the assigned SPNs.
    13
  4. Select Authentication on the Home page of your application and enable Windows Authentication and Anonymous Authentication.
    14
  5. Choose Windows Authentication and click Providers… from the Actions pane. Make sure the following providers are selected and also that the order of these providers is as followed.
    16
  6. Turn off Kernel-mode authentication by selecting Windows Authentication and clicking Advanced Settings… from the Actions pane.
    15
    Note:
    For in-depth information on Kernel-mode authentication and IIS hosted WCF please visit
    this blog post.
  7. To verify that Kerberos authentication is working correctly, connect the WCF Test Client to your web service. Invoke the UploadFile operation with a random string as parameter.
    17
    The upload won’t succeed - however, authentication will occur and you should be able to verify whether it’s Kerberos or NTLM.
  8. To verify the authentication mode, check the Event Viewer on the system running IIS for Audit Success events (Event ID 4624) in Windows Logs –> Security.
    18
    If Kerberos is your Logon Process you have successfully configured your web service for Kerberos authentication.

Configuring the Client for Kerberos Authentication

After adding a service reference to your client project, a few customizations of the config file are required.

App.config

The key customizations of the app.config file are:

  • use wsHttpBinding and configure the required security settings as shown below
  • create an endpoint behavior and set allowedImpersonationLevel = Delegation

App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IKrbService1">
<security>
<message clientCredentialType="Windows" negotiateServiceCredential="true"
establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://red.colors.selfhost.corp.microsoft.com/KRBDemo/KrbService1.svc"
behaviorConfiguration="DelegationBehavior" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IKrbService1" contract="KrbSvc.IKrbService1">
<identity>
<servicePrincipalName value="HTTP/red.colors.selfhost.corp.microsoft.com" />
</identity>
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="DelegationBehavior">
<clientCredentials>
<windows allowedImpersonationLevel="Delegation" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

Set up Kerberos Constrained Delegation

Delegation allows a front-end service to forward the client’s request to a back-end service in such a way that the back-end service can also impersonate the client. Kerberos constrained delegation restricts those back-end services running on specific servers. Since delegation is a Windows domain feature there are a couple of configurations which have to be made on the domain controller.

  1. Open Active Directory Users & Computers on your domain controller.
  2. Locate the service user running the WebServices AppPool (e.g. IIS_SERVICE_RED) and open the Properties window.
  3. Switch to the Delegation tab (which will only be displayed if a service principal name has been defined for this user).
  4. Select Trust this user for delegation to specified services only and Use Kerberos only.
  5. Click Add… to assign an SPN of a service for delegation.
  6. Click Users and Computers… to locate your SharePoint service user in Active Directory.
  7. Select available service (HTTP) and mark it.
    20
  8. Verify that the HTTP service of your SharePoint service user has been assigned for delegation – it must appear in the list of services to which the account can present delegated credentials.
    19
  9. Also double-check that the implementation of your web service is decorated with [OperationBehavior(Impersonation = ImpersonationOption.Required)] as explained in Part 1. Delegation will not work if this attribute is missing.

Testing the File Upload

Finally we need to test the whole demo and check if the file upload is working and delegation happening.

  1. Run the KRBClient on your client machine.
    21
  2. Open the document library in SharePoint and verify that the file has been uploaded successfully. In the Modified By column you should see the name of the user who has initially run the client application.
    22

Summary

In this demo I showed you all the configuration steps needed, so that a client application can connect to a back-end service (e.g. SharePoint) through a WCF web service. Since this demo also shows you how to delegate credentials, it will hopefully help you solving issues, you might run into with your WCF designs.