The objective of this hands-on lab is the creation of:
an on-premises WCF service, hosted on IIS, that consumes identity information from Windows Azure’s Access Control Service;
a console application that uses service.
On Visual Studio, create a new WCF service (WCF Service Application template), named “WhoAmI.svc”, with the following contract:
[ServiceContract]
public interface IWhoAmI
{
[OperationContract]
string Get();
}
The Get
method should return a string with the concatenation of the claims identifiying the requesting user.
Open the Web.config
file and analyze the generated configuration for the service. By default, the HTTP scheme is mapped to basicHttpBinding
.
Create a new IIS web site named “soap.rp.ciws”, and host the WCF service on it using an HTTP binding. Don’t forget to change the hosts
file and application pool version.
Import the certificates and private key for soap.rp.ciws into the adequate stores.
Create a new console client, add a reference to the service and run the client. Note that in this step, the service is not using federated authentication.
Open the “App.config” file and analyze the generated configuration for the service. Note that the binding is basicHttpBinding
.
On the WCF service project, add a new STS Reference. Use the following configurations:
Open the Web.config
file and analyze the changes. Note the:
microsoft.identityModel
sectionws2007FederationHttpBinding
ws2007FederationHttpBinding
federatedServiceHostconfiguration
behavior extensionserviceCredentials
with information about the certificate used by the serviceTest the service, acessing WSDL information. See that the following error is shown
Keyset does not exist
This happens because the identity used for the IIS worker process doesn’t have permissions to read the private key (needed to decrypt incoming messages). You can either change the application pool identity to “Network Service” and give read permissions to the private key or you can use PowerShell to give read permissions to IIS APPPOOL\soap.rp.ciws
.
$cert = ls cert:\LocalMachine\My | where { $_.Subject -match "soap.rp.ciws" }
$pvk_file = "c:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\" + $cert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName
$acl = get-acl $pvk_file
$perm = "IIS APPPOOL\soap.rp.ciws", "Read", "Allow"
$rule = new-object System.Security.AccessControl.FileSystemAccessRule $perm
$acl.SetAccessRule($rule)
$acl | set-acl $pvk_file
Test the client again. An exception should be thrown, since the bindings are now different between the client and the server.
Update the service reference. Open App.config
and analyze the changes. Note that ACS provides multiple issuers and, by default, the first one is used. Comment the issuer
element with the https://demos-ciws.appfabriclabs.com/v2/wstrust/13/issuedtoken-symmetric
address and copy for the same location the issuer
element with the https://demos-ciws.appfabriclabs.com/v2/wstrust/13/username
address.
Test the client again. An exception should be thrown because the revocation could not be checked. Disable certificate revocation validation:
client.ClientCredentials.ServiceCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck;
Test the client again. Another exception should be thrown because the username wasn’t provided. Use the following credentials (already configured in ACS):
client.ClientCredentials.UserName.UserName = "Alice";
client.ClientCredentials.UserName.Password = "changeit";
Test the client again. It should execute successfully and return a string with the claims issued by the ACS.
Add the “soap.rp.ciws” as a new relying party to the ACS tenant created on HOL 2. Change the configuration so that the client uses this new tenant.