Adding InfoCard


What do we need to do to add InfoCard to our application? Well, the key point is that we don't have to write any code to enable InfoCard. We can enable InfoCard via the client and server app.config files.

This is consistent with the WCF vision of enabling administrators to make configuration changes without having to recompile. Everything you can do in config you can still do in code, but by using config files you add deployment flexibility to your application. If you want to limit that flexibility, you can use binding requirements and custom channels to prevent inappropriate changes.

Here we are selecting InfoCard as a credential type in the WCF classes, a way to transfer credentials from the client to the server. Let's start with the server app.config:

We need to update the service binding to use message-level security and the InfoCard credential type, which is IssuedToken:

<bindings>   <wsHttpBinding>     <binding name="helloBinding">       <security mode="Message">         <message clientCredentialType="IssuedToken" />       </security>     </binding>   </wsHttpBinding> </bindings>


Now we'll adjust the client's app.config to match the server. This is identical to the server binding:

<bindings>   <wsHttpBinding>     <binding name="helloBinding">       <security mode="Message">         <message clientCredentialType="IssuedToken" />       </security>     </binding>   </wsHttpBinding> </bindings>


We've specified that the client should use InfoCard to pass credentials to the service, but how does the service identify itself to the client app? How does the clientor, more specifically, the user of the client apptrust the server?

One of the bedrock requirements of the InfoCard system is that any potential recipients of my digital identity must identify themselves to me using cryptographically verifiable but human-friendly means. Only then can I make a rational decision on whether to trust that party and provide them with information.

The way servers identify themselves on the Internet today is by using PKI certificatestypically purchased from Certificate Authorities such as VeriSign or Thawte.

InfoCard takes advantage of this. A service must identify itself using an SSL certificate. Furthermore, the relying party behind the service should identify itself by the use of high-assurance certificates (this is preferred but not mandatory). After all, the user does not trust a service endpoint per se but rather the company or organization providing the service endpoint.

Consequently, the X.509 certificate should identify the organization behind the server and, to help the human in the system, the certificate should utilize logotypes [RFC 3709] for the issuer organization (the Certificate Authority) and the subject organization (the relying party). Logotypes provide a mechanism by which signed JPEG or GIF images are bound to the certificate to help us recognize the relevant parties and make an informed decision to trust or not to trust. It is these logos that are displayed in the trust (or RIP) dialog.

Let's install a certificate for our service to use. You're welcome to try your own, but one place you can find a certificate that uses logotypes is in the Microsoft Federated Identity and Access Resource Kit for Sept 2005 Community Technology Preview. This can be found at http://www.microsoft.com/downloads. However, the code in the Resource Kit will work only with the earlier September WinFx CTP. It will not work with beta 2. We are using it only as a source for some certificates.

When you extract the Resource Kit MSI file, a Certificates-and-Logos folder is created in C:\Program Files\Microsoft Federated Identity and Access Resource Kit - Sept 2005 CTP\InfoCardWalkthrough\StepByStepSamples.

Fabrikam-Contoso.pfx contains the public/private key pair so it needs to be installed on the server (password xyz). Fabrikam-Contoso-Public.cer has just the public key and will need to be installed on the client.

To import, launch the Microsoft Management Console (MMC) from a command prompt and choose Add/Remove Snap-in from the File menu. Next click the Add button and double-click the Certificates snap-in. Choose My user account and Finish, then doubleclick the Certificates snap-in again and choose Computer account, then Local computer and Finish. Close the dialog and click OK.

We import the .pfx file by expanding the Certificates (Local Computer) node, right-clicking the Personal node, and choosing All Tasks and Import. In the wizard make sure you select Fabrikam-Contoso.pfx (the default file type is .cer). As you go through the wizard, keep the defaults, but select Automatically Select the Certificate Store Based on the Type of Certificate. You should get a warning dialog saying that Windows cannot confirm the origin of the certificate and asking whether you still want to install the certificate (you say yes!). This will place the Fabrikam certificate in Local Computer Personal Certificates and an INFOCARD certificate in Trusted Root Certification Authorities Certificates. You will need to do a refresh for the certificates to show up in the MMC UI.

For the client we need access to a certificate containing (just) the public key. So we import the .cer file by expanding the CertificatesCurrent User node, right-clicking the Trusted People node, and doing an import of the Fabrikam-Contoso-Public.cer file, making sure that the certificate gets placed in the Trusted People store.

Now we can modify the client and service app.config files so that WCF and InfoCard can locate and use these certificates. Let's start with the service and its app.config.

The correct mechanism for hooking up WCF to a resource on the local machine is to use a behavior. This should sit beneath the entire <bindings> section (that is, between </bindings> and </system.serviceModel>):

<behaviors>   <behavior name="helloServiceBehavior"     returnUnknownExceptionsAsFaults="true" >     <serviceCredentials>       <serviceCertificate         findValue="Fabrikam"         storeLocation="LocalMachine"         storeName="My"         x509FindType="FindBySubjectName" />       </serviceCredentials>   </behavior> </behaviors>


Here you can see we are using a certificate called Fabrikam in the LocalMachine Personal ("My") store. If you've used your own certificates (for example, from a certificate authority, Certificate Services, or the makecert utility), you will need to make the appropriate changes.

We refer to the behavior by adding a behaviorConfiguration attribute to our service description:

<service   name="HelloService.Hello"   behaviorConfiguration="helloServiceBehavior">


We have now enabled WCF to access the certificate and the private key so that it can now use it for signing and decryption. However, we are not quite finished because we need to allow access to the certificate via an endpoint reference to enable identity and token encryption. Our entire <services> section now looks like this:

<services>   <service     name="HelloService.Hello"     behaviorConfiguration="helloServiceBehavior">     <endpoint       address="helloEndpoint"       contract="HelloService.IHello"       binding="wsHttpBinding"       bindingConfiguration="helloBinding">       <identity>         <certificateReference           findValue="Fabrikam"           storeLocation="LocalMachine"           storeName="My"           x509FindType="FindBySubjectName" />       </identity>     </endpoint>   </service> </services>


After this is in place, we have finished our service configuration. Next is the client's app.config. On the server side we need a behavior to access the private key. On the client we can either add a behavior or use the MetadataResolver class to retrieve the certificate information via WS-MetadataExchange. Let's take the behavior approach:

<behaviors>   <behavior name="helloClientBehavior">     <clientCredentials>       <serviceCertificate>         <authentication           certificateValidationMode="PeerOrChainTrust"/>         <defaultCertificate           findValue="Fabrikam"           storeLocation="CurrentUser"           storeName="TrustedPeople"           x509FindType="FindBySubjectName" />       </serviceCertificate>     </clientCredentials>   </behavior> </behaviors>


And add a reference to that behavior:

<client>   <endpoint     name="helloClient"     address="http://localhost:4123/helloService/helloEndpoint"     contract="HelloService.IHello"     binding="wsHttpBinding"     bindingConfiguration="helloBinding"     behaviorConfiguration="helloClientBehavior">   </endpoint> </client>


And again we need to allow the InfoCard system access to encrypt the identity so our <client> section looks like this:

<client>   <endpoint     name="helloClient"     address="http://localhost:4123/helloService/helloEndpoint"     contract="HelloService.IHello"     binding="wsHttpBinding"     bindingConfiguration="helloBinding"     behaviorConfiguration="helloClientBehavior">     <identity>       <certificateReference         findValue="Fabrikam"         storeLocation="CurrentUser"         storeName="TrustedPeople"         x509FindType="FindBySubjectName" />     </identity>   </endpoint> </client>


Now comes the moment of truth: Run the application and see what happens. If all goes well, you should get the Trust dialog, looking something like what's shown in Figure 14.6. You'll see how to display the logos in a moment.

Figure 14.6. Trust dialog.


You click Yes, Choose a Card to Send; then, if you already have some cards, you will get what is shown in Figure 14.7.

Figure 14.7. Choosing an InfoCard.


If you have yet to create any cards, you will see a dialog similar to the Add Cards dialog shown earlier where you have the choice of creating a new Personal ("self-issued") card, installing a card provided to you by an identity provider (a .crd file), restoring an exported card (a .crds file), or simply returning to the website without doing anythingthe user is in control!

After you choose a personal card, a security token is created by the personal STS and, with your approval, sent to the service. The service doesn't actually do anything with the security token at this point and simply displays "Hello World."

Step through the code so that you understand at exactly which point the InfoCard dialog is launched.

If you don't choose a card, you will get an ugly Unhandled Exception error, so let's add some code to the client to catch the exception and handle it gracefully. In the HelloClient project, add a reference to System.IdentityModel.Selectors and open Program.cs. Next add the following statement at the top of the file:

using System.IdentityModel.Selectors;


Then in the body of Program.cs modify Main() so that it looks like the following:

static void Main(string[] args)         {             try             {                 ChannelFactory<HelloService.IHello> cnFactory =                     new ChannelFactory<HelloService.IHello>("helloClient");                 HelloService.IHello chn = cnFactory.CreateChannel();                 Console.WriteLine(chn.Say());                 cnFactory.Close();             }             catch (UserCancellationException)             {                 Console.WriteLine("User has cancelled");             }             catch (UntrustedRecipientException)             {                 Console.WriteLine("User does not trust the recipient");             }             catch (ServiceNotStartedException)             {                 Console.WriteLine("InfoCard service not started");             }             catch (InfoCardException ice)             {                 Console.WriteLine("Generic InfoCard exception :" + ice.Message);             }             catch (Exception e)             {                 Console.WriteLine("Other exceptions :" + e.Message);             }             finally             {                 Console.ReadKey();             }         }


Experiment a bit and see whether the exceptions are caught properly.

As stated previously, the service's certificate includes links to the subject and issuer logos. To verify this, you can open up MMC and the Certificates snap-in and look at the properties of the Fabrikam certificate. Under the 1.3.6.1.5.5.7.1.12 field there are links to the subject and issuer logos.

http://localhost/ServiceModelSamples/fabrikam.gif is the link for the subject logo; http://localhost/ServiceModelSamples/contoso.gif is the link for the issuer logo. These logos cannot be modified because a hash of each logo is also a part of the certificate. However, for these logos to be accessed, we need to place them in an http://localhost/ServiceModelSamples virtual directory.

Use the Internet Manager (inetmgr.exe) MMC snap-in to create a virtual directory called ServiceModelSamples under the Default Web Site (choose context menu, New, Virtual Directory) and point it at the directory containing the certificates. Accept the default settings elsewhere in the wizard.

Launch Internet Explorer and make sure that the logos display correctly using the URLs given earlier:

http://localhost/ServiceModelSamples/fabrikam.gif

http://localhost/ServiceModelSamples/contoso.gif

Now run the application again and you should see the logos appear in the Trust dialog.

Where would these logos be hosted in real life? Normally, a relying party would host its logo (the subject), and the issuer's logo would be hosted by the Certificate Authority. Alternatively, a third party could provide the hosting service.




Presenting Microsoft Communication Foundation. Hands-on.
Microsoft Windows Communication Foundation: Hands-on
ISBN: 0672328771
EAN: 2147483647
Year: 2006
Pages: 132

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net