Skip to main content

Security Interoperability Guideline between WCF-WIF and IBM WebSphere Application Server

By Jesus Rodriguez, Chief Architect, Tellago, Tellago Studios, Inc

Technical Reviewers:

Kent Brown, Microsoft

Kirill Gavrylyuk, Microsoft

Michael Green, Microsoft

ON THIS PAGE

 

The Case for WS-* Security Interoperability in 2010 

Security is a fundamental element for the successful adoption of Web Services in enterprise solutions in the real world. The ability to sign, encrypt, trust and federate messages exchanged between service providers and consumers is no longer a fancy requirement but rather a vital element to guarantee the success of Service Orientation in the enterprise. In that regard, the industry has produced a series of security specifications, commonly known as WS-* protocols, that model some of the fundamental security patterns required by service oriented solutions. Specifically, different flavors of WS-* protocols such as WS-Security, WS-SecureConversation, WS-Trust and WS-Federation have become the cornerstone of Web Service security mechanisms like message protection, token exchange, trust and federation respectively.

Contrary to the limited industry adoption seen by other WS-* specifications, the WS-* security protocols have been widely used across a large variety of industries such as Government, Health Care, Financial sector, among many others. The reason for this difference is that those industries have a large variety of identity trust and federation scenarios that are highly difficult to implement with alternative architecture styles such as RESTful services. This adoption has also been influenced by more mainstream technologies such as Microsoft's SharePoint Server that has embraced some of these WS-* protocols as the foundation to implement some of their security capabilities. Additionally, we are witnessing how new technologies such as the Windows Identity Foundation (WIF) are making the implementation, deployment and management of those scenarios more accessible to the average developer.

The evolution of the adoption of WS-* security protocols has increased the need for seamless interoperability across the different Web Service technology stacks. This need is particularly important across the Web Services stacks such as Windows Communication Foundation (WCF) and IBM WebSphere that have a large footprint in Service Oriented environments in the large enterprise.

The rest of this paper covers some of the most common WS-* security interoperability scenarios between Microsoft's WCF-WIF and IBM's WebSphere. The paper includes detailed explanations of the scenarios as well as the techniques required to implement services and client on both technology stacks.

A Look at WCF-WIF and WebSphere from the Security Standpoint.

Web Services Security in WCF and WIF

Since its first release (3.0), Windows Communication Foundation (WCF) has provided the infrastructure to implement various Web Service security capabilities such as authentication, authorization, message protection, trust and federation. WCF achieves this by leveraging its implementation of various WS-* security protocols like WS-Security, WS-SecureConversation, WS-Trust and WS-Federation as well as complimentary security standards such as WS-SecurityPolicy and SAML.

In the WCF programming model, the implementation of the WS-* security protocol is abstracted by a series of components known as protocol channels. From a runtime perspective, protocol channels execute right before or after the transport channel which is responsible for sending or receiving messages using a specific transport protocol. The specific security settings are communicated by using WCF bindings and behaviors either programmatically or via configuration. This set of settings ultimately produces the WS-SecurityPolicy for the specific service. Figure 1 below illustrates this model.

Figure 1: WCF Security model

The model explained previously, enables WCF to provide a sophisticated model to implement very complex Web Service security scenarios. Among those scenarios, the implementation of a brokered security pattern based on the concept of a security token service (STS) could still require a significant amount of code and deep understanding of the underlying protocol. In order to abstract the complexity of a brokered model and extend it beyond WCF services, Microsoft recently released the first version of Windows Identity Foundation (WIF). WIF provides a flexible model that abstracts the components of a claims-based brokered security model as illustrated in the Figure 2 below..

Figure 2: Claims-based brokered security model

Essentially, WIF provides a very simple programming model to implement the fundamental components of identity-aware applications such as claims generation, authorization, and security token creation among many others. In a nutshell, WIF is perhaps a better option if you are looking to implement a brokered security pattern based on a WS-Trust or WS-Federation STS.

Web Services Security in WebSphere Server

Similar to other J2EE application servers, IBM WebSphere server provides the infrastructure for building, hosting and managing Web Services based on the JAX-RPC and JAX-WS models. In that sense, WebSphere Server enables security capability across both Web Services technology stacks. Even though JAX-WS is an evolution of the JAX-RPC model that supports most of the newest generation of Web Service specifications, JAX-RPC still has a considerable footprint in WebSphere enterprise applications.

From the security standpoint,IBM WebSphere Serverupports various versions of WS-Security, WS-SecureConversation and WS-Trust as well as complimentary standards such as SAML and WS-SecurityPolicy. In the current version, some of those WS-* security protocols are enabled in both JAX-WS and JAX-RPC models while other capabilities are exclusively available in one of the models. Both programming models provide a flexible handler framework that provides a common interface for abstracting the implementation of the various WS-* security protocols. Figure 3 below illustrates that concept:

Figure 3: IBM WebSphere Web Services security model

As WebSphere's JAX-WS implementation continues evolving, it should enable the majority of the capabilities included in the different WS-* security protocols. Looking at the previous diagram you might have noticed that we have highlighted the use of WS-Policy. Unlike WCF, which abstracts policies through bindings and binding elements, WebSphere Web Services and clients interact directly with WS-SecurityPolicy policies to configure the security requirements of the services and client runtimes respectively. This dependency is incredibly important from the interoperability standpoint, given that it forces architects to model interoperable policies from the very beginning of the service development lifecycle.

When using JAX-WS Web Services, WebSphere Application Server uses the policy set model for implementing the Web Services Security Version 1.1 specification, the Username token Version 1.1 profile, and the X.509 token Version 1.1 profile. Policy sets combine configuration settings, including those for transport and message level configuration, such as WS-Addressing, WS-SecureConversation, and WS-Security. In the case of JAX-RPC Web Services, WebSphere uses a series of settings (not policy driven) to configure the correct security model. The current version of WebSphere provides a series of configuration wizards that helps developers to configure the security settings when using JAX-RPC.

When reading this section, you might have realized that there are fundamental differences between the WebSphere and WCF-WIF security models. Despite these differences, both technology stacks provide the infrastructure for implementing very complex Web Service message security scenarios based on various WS-* security protocols. This sophisticated set of capabilities has been a key element in the significant footprint that both WCF-WIF and WebSphere has established in large SOA enterprise applications. Based on that, it's not uncommon to find Web Service security scenarios that require certain levels of interoperability between these two technology stacks.

Web Service Security Interoperability Scenarios

The remaining sections of this paper will explore a set of the most common web services security interoperability scenarios between IBM WebSphere and Microsoft WCF. In order to keep things practical, we have decided to go beyond the fundamental capabilities of each scenario and deep dive into the specific implementation techniques that developers need to follow in order to accomplish bidirectional interoperability between WCF-WIF and WebSphere services. Specifically, we will focus on the following scenarios:

  • WS-Security interoperability using Username+Password and X509 Certificates
  • WS-Security interoperability using double X509 Certificates
  • WS-SecureConversation interoperability
  • WS-Trust interoperability

In order to keep things consistent, we use the same Web Service contract and implementation across all of our samples. The WCF implementation is illustrated in the following code, Figure 4:

[ServiceContract]
public interface ISampleService
{
    [OperationContract]
    int Add(int param1, int param2);
}

public class SampleService : ISampleService
{
    public int Add(int param1, int param2)
    {
        return param1 + param2;
    }
}

Figure 4: WCF service implementation

Similarly the WebSphere implementation looks like the following code, Figure 5:

@WebService(name = "SampleService_WSSecConv_UNT", 
            serviceName = "SampleService_WSSecConv_UNT", 
            portName = "SampleService_WSSecConv_UNTSoap12HttpPort")
@BindingType(SOAPBinding.SOAP12HTTP_BINDING)
public class SampleService {
    public SampleService() {
        super();
    }
    
    public int Add(int param1, int param2)
    {
        return param1 + param2;
        }
}

Figure 5: WebSphere Web Service sample implementation

Even though the implementation highlighted above is using a JAX-WS model, you will find a similar JAX-RPC implementation in our samples. We will constantly reference this Web Service as part of the scenarios included in this paper. The first of these scenarios illustrates the interoperability between WCF and WebSphere using WS-Security with username and password client credentials.

WS-Security Interoperability Using Username and Password Client Credentials

Overview

Using username credentials protected with X509 certificates is arguably the most common WS-Security scenario in service oriented environments. In this scenario a client application authenticates to the service using username and password credentials while the service authenticates back to the client using a specific certificate. Figure 6 below illustrates the concept:

Figure 6: WS-Security using username client credentials

Based on its simplicity, this security model has been widely adopted by a large number of enterprise and internet web services APIs making its interoperability a common requirement in heterogeneous service oriented solutions.

WS-Security with username client interoperability using a WCF Service and a WebSphere Client

WCF Service

Given that WCF natively supports the WS-Security with username credentials profile, we can easily adapt our sample WCF service to support this scenario by configuring the service endpoint using a version of the ws2007HttpBinding binding with the following settings, Figure 7.

<system.serviceModel>
 <services>
   <service name="SampleService"   
     behaviorConfiguration="ServiceCredentialsBehavior">
     <endpoint name="wssunt" address="" contract="ISampleService"
               binding="ws2007HttpBinding" 
               bindingConfiguration="wssuntBinding">
       <identity>
         <dns value="Alice"/>
       </identity>
     </endpoint>
   </service>
 </services>
 <bindings>
   <ws2007HttpBinding>
     <binding name="wssuntBinding">
       <security mode="Message"  >
         <message  clientCredentialType="UserName" 
                   establishSecurityContext="false"
                   algorithmSuite="Basic256" 
                   negotiateServiceCredential="false" />
       </security>
     </binding>
   </ws2007HttpBinding>
 </bindings>
 <behaviors>
   <serviceBehaviors>
     <behavior name="ServiceCredentialsBehavior">
       <serviceMetadata httpGetEnabled="true"/>
       <serviceDebug includeExceptionDetailInFaults="true"/>
       <serviceCredentials>
         <userNameAuthentication userNamePasswordValidationMode="Custom"                           
                                 customUserNamePasswordValidatorType=
"Microsoft.ServiceModel.InteropSamples.Extensions.CustomUserNameValidator, Microsoft.ServiceModel.InteropSamples.Extensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
         <serviceCertificate 
                findValue="6e0e88f36ebb8744d470f62f604d03ea4ebe5094"
                storeLocation="LocalMachine" storeName="My"  
                x509FindType="FindByThumbprint"/>
         <clientCertificate>
           <authentication certificateValidationMode="PeerOrChainTrust" />
         </clientCertificate>
       </serviceCredentials>
     </behavior>
     ...
   </serviceBehaviors>
 </behaviors>
</system.serviceModel>

Figure 7: WCF service configuration settings

As illustrated in the previous code, the security model is expressed by the WCF binding configuration while the specific credentials are modeled as part of a WCF service behavior. To be more specific, in order to configure our sample WCF service endpoint to support WS-Security with a username client is simply a matter of creating a custom ws2007HttpBinding configuration specifying the username credential type and disabling the use of WS-SecureConversation (establishSecurityContext="false", negotiateServiceCredential="false"). Details of the specific configuration settings for this WS-Security model can be found as part of the WCF documentation (http://msdn.microsoft.com/en-us/library/ms731058.aspx)

In addition to that configuration, we need to indicate the specific security artifacts used by our service. In our previous code, this is accomplished by using a custom service behavior (ServiceCredentialsBehavior) in which we configure the specific certificate used by our service as well as the mechanism used to validate the username/password credentials provided by the client (CustomUserNameValidator). Given that the client application might not necessarily use Windows credentials, we've decided to implement a custom username validator illustrated in the following code, Figure 8.

public class CustomUserNameValidator : UserNamePasswordValidator
   {
       public override void Validate(string userName, string password)
       {
           if ("test" != userName || "test" != password)
           {
               throw new ArgumentNullException();
           } 
       }
   }

Figure 8: Custom username and password validator

This custom validator is added to the WCF runtime by the service credentials behavior included in the previous configuration.

At this point, our WCF service is properly configured to accept WS-Security messages that include the username/password credentials and authenticate back to the client using X509 certificate.

WSP Client

As explained in previous sections, the current version of WebSphere Server (WSP) natively supports the WS-Security with username credentials profile. This makes it extremely simple to implement a WSP client that interacts with our WCF service. The service certificates required to protect the message exchange as well as to authenticate the service should be configured in a Java Key Store accessible to the WSP client. More details about how to create a Java Key Store are included in the Appendices section of this paper.

The first step to implement our WSP client is to generate a JAX-WS proxy for our WCF service. We can easily accomplish that using the Web Service client wizards included in IDEs such as IBM WebSphere Studio. Alternatively, you could include the following Ant task as part of your build.xml file, as in Figure 9 below:

<taskdef name="clientgen"
    classname="WebSphere.wsee.tools.anttasks.ClientGenTask" />
 <target name="build-client">
    <clientgen
      wsdl="WSDL URL..."
      destDir="clientclasses"
      packageName="examples.webservices.simple_client"
      type="JAXWS"/>
 </target>

Figure 9: Ant task to generate a JAX-WS proxy

By using any of the aforementioned mechanisms, WSP will generate a service proxy that is preconfigured to use the WS-Security policy exposed by our WCF service. Remember that the WSP runtime directly interprets WS-Securitypolicies instead of relying on an intermediate abstraction as WCF does. At this point, it is just a matter of passing the correct credentials to the JAX-WS runtime as illustrated in the following code, Figure 10:

public class WS2007HttpBinding_ISampleServiceClient
{
 @WebServiceRef
 private static SampleService sampleService;

   public static void main(String[] args) {
       try {
           sampleService = new SampleService();
           ISampleService iSampleService = sampleService.getWS2007HttpBinding_ISampleService();

           Map<String, Object> requestContext = ((BindingProvider) iSampleService).getRequestContext();
           
           List credProviders = new ArrayList();
           CredentialProvider untProvider= 
           WssuntClient.getUNTCredentialProvider("test", "test") ;
           
           requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, 
                                                "Service endpoint....");
           
           CredentialProvider certProvider= 
           WssuntClient.getBSTCredentialProvider("wsinterop.jks", "password",
                      "Alice", "password", 
                      "wsinterop.jks", "password", "Alice", requestContext);
           credProviders.add(untProvider);
           credProviders.add(certProvider);
           requestContext.put(WSSecurityContext.CREDENTIAL_PROVIDER_LIST, credProviders);
       
           int result= iSampleService.add(11,11);
           System.out.println(result);

       } catch (Exception ex) {
           ex.printStackTrace();
       }
   }
   ....
   }

Figure 10: Java client using WS-Security with username credentials

Looking at the previous code, you can notice that our client uses two credential providers configured with the username-password and certificates used by the client and service respectively.

The previous code is everything we need in order to effectively communicate with our WCF service. The following section explores the same security scenario, but this time using a WSP service and a WCF client.

WS-Security with username client interoperability using a WebSphere Service and a WCF Client

Implementing a WSP Service

Implementing a WebSphere (WSP) service that leverages WS-Security with a username and password credentials is as simple as configuring it with the appropriate WS-SecurityPolicy assertions. The current version of WSP includes a large number of preconfigured policies that abstract some of the major web service security scenarios. Additionally, we can use custom policies by deploying the policy files to /WEB-INF/Policies folder of the specific solution or to the default WSP policy store. In our sample scenario, we are using the following WS-SecurityPolicy, see Figure 11 below.

<wsp:Policy wsu:Id="wssunt_policy">
       <wsp:ExactlyOne>
           <wsp:All>
               <sp:SymmetricBinding xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
                   <wsp:Policy>
                       <sp:ProtectionToken>
                           <wsp:Policy>
                               <sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never">
                                   <wsp:Policy>
                                       <sp:RequireDerivedKeys/>
                                       <sp:RequireThumbprintReference/>
                                       <sp:WssX509V3Token10/>
                                   </wsp:Policy>
                               </sp:X509Token>
                           </wsp:Policy>
                       </sp:ProtectionToken>
                       <sp:AlgorithmSuite>
                           <wsp:Policy>
                               <sp:Basic256/>
                           </wsp:Policy>
                       </sp:AlgorithmSuite>
                       <sp:Layout>
                           <wsp:Policy>
                               <sp:Strict/>
                           </wsp:Policy>
                       </sp:Layout>
                       <sp:IncludeTimestamp/>
                       <sp:EncryptSignature/>
                       <sp:OnlySignEntireHeadersAndBody/>
                   </wsp:Policy>
               </sp:SymmetricBinding>
               <sp:SignedEncryptedSupportingTokens xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
                   <wsp:Policy>
                       <sp:UsernameToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
                           <wsp:Policy>
                               <sp:WssUsernameToken10/>
                           </wsp:Policy>
                       </sp:UsernameToken>
                   </wsp:Policy>
               </sp:SignedEncryptedSupportingTokens>
               <sp:Wss11 xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
                   <wsp:Policy>
                       <sp:MustSupportRefThumbprint/>
                       <sp:MustSupportRefEncryptedKey/>
                   </wsp:Policy>
               </sp:Wss11>
               ...
               <wsaw:UsingAddressing/>
           </wsp:All>
       </wsp:ExactlyOne>
   </wsp:Policy>

Figure 11: WS-Security username client policy

After deploying this policy to the WSP server, we can configure our web service to use it by using the following annotations, see Figure 12.

@WebService(name = "SampleService_WSSecConv_UNT", serviceName = "SampleService_WSSecConv_UNT",
portName = "SampleService_WSSecConv_UNTSoap12HttpPort")
@BindingType(SOAPBinding.SOAP12HTTP_BINDING)
@Policy(uri = "policy:Wssp1.2-UNTPolicy.xml")
public class SampleService {
   public SampleService() {
       super();
   }
   
   public int Add(int param1, int param2)
   {
       return param1 + param2;
       }
}

Figure 12: Web service configuration

Notice that the policy is specified as an annotation to the service class. At this point, our WSP service is properly configured based on our WS-Security profile and it can be deployed to a WSP instance. It’s is important to notice that the certificates used for the service and client credentials should be correctly configured in the WebSphere Application Server. We can accomplish that by using the WebSphere administration console included in the current version of the application server. Let's continue by exploring now how to create a WCF client that interacts with our sample WSP service.

Implementing a WCF Client

The first task in order to implement a WCF client that interacts with the WSP service implemented in the previous section, is to generate the corresponding WCF service proxy by either using the Add Service Reference feature included in Visual Studio or the svcutil command line tool. After that we need to set the corresponding bindings and behaviors that match our service security profile. Similar to the WCF service implementation explained in a previous section, our WCF client endpoint will use a specific configuration of the ws2007HttpBinding to specify the proper security mechanism. The specific credentials used by our client and service are detailed as part of a service behavior configuration. Figure 13 illustrates our client configuration.

<system.serviceModel>
   <bindings>
       <ws2007HttpBinding>
         <binding name="wssuntBinding">
           <security mode="Message"  >
             <message  clientCredentialType="UserName" establishSecurityContext="false"
                      algorithmSuite="Basic256" negotiateServiceCredential="false" />
           </security>
         </binding>
       </ws2007HttpBinding>
   </bindings>
   <client>
     <endpoint address="service endpoint..."
         binding="ws2007HttpBinding" bindingConfiguration="wssuntBinding"
         contract="ISampleService" name="wssuntClient" behaviorConfiguration="SecBehavior">
       <identity>
         <dns value="Alice"/>
       </identity>
     </endpoint>
   </client>
   <behaviors>
     <endpointBehaviors>
       <behavior name="SecBehavior">
           <clientCredentials>
             <serviceCertificate>
               <defaultCertificate   findValue="6e0e88f36ebb8744d470f62f604d03ea4ebe5094"
                               storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint"/>
               <authentication certificateValidationMode="None"/>
             </serviceCertificate>
           </clientCredentials>
       </behavior>
     </endpointBehaviors>
   </behaviors>
 </system.serviceModel>

Figure 13: WCF client configuration

Similar to previous configurations, the binding section specifies the WS-Security with username credentials models while the endpoint behavior details the specific credentials to be used by the client applications. More details about the specific configuration settings for this WS-Security model can be found as part of the wCF documentation (http://msdn.microsoft.com/en-us/library/ms731058.aspx). After setting this configuration, we can implement our sample WCF client as shown in the following code, Figure 14.

public void WSSUserNameAndPasswordTest()
{
 SampleServiceClient service = new SampleServiceClient("wssuntClient");
 service.ClientCredentials.UserName.UserName = "test";
 service.ClientCredentials.UserName.Password= "test";
 int result = service.Add(11, 11);
}

Figure 14: WCF Client

It is important to highlight that the client credentials are specified as part of the code and not via configuration. This is mostly due to the fact that WCF does not include a configuration representation for username and password credentials.

The following section will explore another very common WS-Security interoperability scenario that uses mutual certificates for authentication and message protection.

WS-Security Interoperability Between WCF and WebSphere: Mutual Certificates

Overview

The previous section highlighted the techniques to interoperate WCF and WebSphere (WSP) services using WS-Security with username client credentials. In spite of the popularity of username and password credentials for client authentication, this model is not always applicable in client-web services interactions. This is particularly relevant in scenarios in which the client is not a user-centric application and requires other mechanisms to authenticate to the backed service.

In order to address these scenarios, it's very common to use a WS-Security profile in which both the client and service use certificates for authentication. Figure 15 below helps to illustrate this concept.

Figure 15: WS-Security with mutual certificates model

This type of WS-Security model, traditionally known as mutual certificate authentication, is very popular to secure the interaction between internal enterprise clients and services. Its popularity also increases the need to guarantee the interoperability of this WS-Security profile across the major web service technology stacks. As part of their current releases, both WCF and WSP natively support the use of WS-Security with mutual certificate credentials.

In their current releases, both WCF and IBM WebSphere Server (WSP) natively support the use of WS-Security with mutual certificate credentials. In that sense, there are no major challenges in terms of achieving interoperability for this security profile between clients and services implemented in these technology stacks. The following sections deep dive into the techniques that developers can use to implement interoperable web services that leverage WS-Security with mutual certificates on WCF and WSP.

WS-Security with Mutual Certificates Interoperability Using a WCF Service and a WSP Client

WCF service

Since its first release, WCF provided native support for the use of WS-Security with double certificates. In that sense, implementing a service that supports this WS-Security profile is as simple as setting the correct configuration using the correct security bindings. Specifically, we can use WCF's wsHttpBinding and ws2007HttpBinding to enable this security profile by just configuring a few attributes. The following code, Figure 16, illustrates the configuration required to enable WS-Security with mutual certificates for our sample service.

<system.serviceModel>
 <services>
	<service name="SampleService" behaviorConfiguration="ServiceCredentialsBehavior">
		<endpoint name="wsscert" address=""
		 contract="ISampleService" binding="ws2007HttpBinding"
		 bindingConfiguration="wsscertBinding">
	         ...
		</endpoint>
  </service>
 </services>
 <bindings>
	<ws2007HttpBinding>
	 <binding name="wsscertBinding">
		<security mode="Message">
		 <message clientCredentialType="Certificate" 
            establishSecurityContext="false" 
            algorithmSuite="Basic256"
            negotiateServiceCredential="false"/>
		</security>
	 </binding>
	</ws2007HttpBinding>
 </bindings>
  <behaviors>
	<serviceBehaviors>
	  <behavior name="ServiceCredentialsBehavior">
		<serviceMetadata httpGetEnabled="true"/>
		<serviceDebug includeExceptionDetailInFaults="true"/>
		<serviceCredentials>
		<serviceCertificate 
               findValue="6e0e88f36ebb8744d470f62f604d03ea4ebe5094" 
               storeLocation="LocalMachine" storeName="My"    
               x509FindType="FindByThumbprint"/>
		<clientCertificate>
		  <authentication certificateValidationMode="PeerOrChainTrust"/>
	     </clientCertificate>
		</serviceCredentials>
     </behavior>			
</system.serviceModel>

Figure 16: WS-Security with mutual certificates WCF configuration

As illustrated in the previous configuration, the mutual certificate model is specified by the ws2007HttpBinding configuration. Specially, we should set the clientCredentialType attribute of the ws2007HttpBinding configuration to Certificate to indicate that the service endpoint expects an X509 certificate as the user credentials. Another important element in the previous configuration is the use of a service behavior to express the specific credentials used by the service and the clients. More details about the specific configuration for this security model can be found in this section of the WCF documentation (http://msdn.microsoft.com/en-us/library/ms733102.aspx)

There is no additional configuration or code required to enable WS-Security with mutual certificates in a WCF service. Let's now explore how to implement a WebSphere (WSP) client that interoperates with this WCF service.

WebSphere Client

The implementation of a WebSphere (WSP) client that interoperates with our sample service using WS-Security with mutual certificates follows a very simple and intuitive pattern for both JAX-WS and JAX-RPC models. This simplicity is mostly due to the native support WSP provides for this security model which guarantees that the WSP runtimes can seamlessly interpret the policies associated with the WCF service.

The first step required to implement a WSP client that interacts with our sample WCF service is to generate a WSP proxy using any of the various web service proxy tools available with the WebSphere runtime. If you are using an IDE such as IBM WebSphere Rational Studio or Eclipse you can leverage the web service client generation wizards available with this IDEs. After we generate the proxy we can start implementing our sample client which leverages WS-Security with double certificates. The following code, Figure 17, illustrates a sample WSP client that interacts with the WCF service created in the previous section.

public class WsscertClient
{
 @WebServiceRef
 private static SampleService sampleService;

   public static void main(String[] args) {
       try {
           sampleService = new SampleService();
           ISampleService iSampleService = sampleService.getWsscert();         
           Map<String, Object> requestContext = ((BindingProvider) 
                                   iSampleService).getRequestContext();            
           List credProviders = new ArrayList();
           requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
            "Service endpoint...");
           
           CredentialProvider certProvider= 
                 WsscertClient.getBSTCredentialProvider("wsinterop.jks",  
                        "password","Alice", "password", "wsinterop.jks",
                        "password", "Alice", requestContext);
      
           credProviders.add(certProvider);
           requestContext.put(WSSecurityContext.CREDENTIAL_PROVIDER_LIST, 
                                                           credProviders);
           
           int result= iSampleService.add(11,11);
           System.out.println(result);

       } catch (Exception ex) {
           ex.printStackTrace();
       }
   }
 }

Figure 17: WSP client using WS-Security with mutual certificates

The previous code performs three fundamental steps. We start by creating a new instance of the JAX-WS proxy generated in the previous steps. After that, we add the certificate credentials that will be used to authenticate to the WCF service and to protect the message. We accomplish that by inserting our certificate credentials provider in the request context’s credential provider list. It is important to notice that these certificates should be accordingly deployed in a Java key store. For illustrative purposes, we’ve specified the certificate credentials (certificate name and password) directly in code. In real applications, is most likely that these parameters would be extracted from some sort of secure configuration store. After this we can invoke the target operation in the WCF service. At this point, the WSP runtime will encode the message into a WS-Security envelope that follows the mutual certificate policy specified in the WCF service WSDL. As you can see, the WSP capability of interpreting the WS-Security policies abstracts the entire infrastructure required to implement the WS-Security with mutual certificates profile. This capability is also relevant when implementing WSP services.

The following section illustrates the techniques required to implement this scenario but this time using a WSP service and a WCF client.

WS-Security with Mutual Certificates Interoperability Using a WSP service and a WCF Client

WSP service

Similar to some of the other scenarios explored in this paper, the implementation of the WSP service that leverages WS-Security with mutual certificates requires configuration of the appropriate WS-SecurityPolicy assertions that express the security model required by the service endpoint. In addition to the policies already included with WSP, we can use custom policies by deploying the specific policy files to the /WEB-INF/Policies folder of the specific solution or to the default WSP policy store. In our sample scenario, we are using the following WS-SecurityPolicy. For our specific scenario, we will use the policy illustrated in the following code, Figure 18:

<wsp:Policy wsu:Id="wsscert_policy">
<wsp:ExactlyOne>
  <wsp:All>
	<sp:SymmetricBinding 
	xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
	<wsp:Policy>
	 <sp:ProtectionToken>
	  <wsp:Policy>
	   <sp:X509Token 
		sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never">
	     <wsp:Policy>
			<sp:RequireDerivedKeys/>
			<sp:RequireThumbprintReference/>
			<sp:WssX509V3Token10/>
 		</wsp:Policy>
	   </sp:X509Token>
	  </wsp:Policy>
	 </sp:ProtectionToken>
	<sp:AlgorithmSuite>
	<wsp:Policy>
	  <sp:Basic256/>
	</wsp:Policy>
	</sp:AlgorithmSuite>
	<sp:Layout>
	<wsp:Policy>
	  <sp:Strict/>
	</wsp:Policy>
	</sp:Layout>
	<sp:IncludeTimestamp/>
	<sp:EncryptSignature/>
	<sp:OnlySignEntireHeadersAndBody/>
 </wsp:Policy>   
</sp:SymmetricBinding>
			<sp:EndorsingSupportingTokens xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
				<wsp:Policy>
					<sp:X509Token 
					sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
						<wsp:Policy>
							<sp:RequireThumbprintReference/>
							<sp:WssX509V3Token10/>
						</wsp:Policy>
					</sp:X509Token>
				</wsp:Policy>
			</sp:EndorsingSupportingTokens>
			...
		</wsp:All>
	</wsp:ExactlyOne>
</wsp:Policy>

Figure 18: WS-Security with mutual certificates policy

After deploying the previous policy to WSP, we can leverage it in our sample web service using the JAX-WS @Policy annotation as illustrated in the following code, Figure 19.

@WebService(name = "SampleService_WSS_MutualCert", serviceName = "SampleService_W WSS_MutualCert",
portName = "SampleService_ WSS_MutualCert_Soap12HttpPort")
@BindingType(SOAPBinding.SOAP12HTTP_BINDING)
@Policy(uri = "policy:Wssp1.2-MutualCertPolicy.xml")
public class SampleService {
   public SampleService() {
       super();
   }
   
   public int Add(int param1, int param2)
   {
       return param1 + param2;
       }
}

Figure 19: WSP service that uses WS-Security with mutual certificates (you can find the complete code in the examples attached to this paper)

At this point we can deploy our sample service to a WSP instance. The specific certificates to be used by this service are configured as part of the WSP WS-Security settings. You can refer to the appendicies section for the specific steps of how to configure and modify these settings. Let's now explore how to build a WCF client that invokes our sample service.

WCF client

Similar to our WCF service implementation explored previously, we can enable WS-Security with mutual certificates on a WCF client using only configuration. Specifically, we will rely on the ws2007HttpBinding to indicate the use of certificates as the authentication mechanism as illustrated in the following code, Figure 20:

<system.serviceModel>
   <client>
     <endpoint name="wssMutualCert_Client"
      address="service endpoint..."
      binding="ws2007HttpBinding"  
      bindingConfiguration="wssMutualCertBinding"
      contract="ISampleService" 
      behaviorConfiguration="MutualCertBehavior">
       <identity>
         <dns value="Alice"/>
       </identity>
     </endpoint>
   </client>
  
    <bindings>
      <ws2007HttpBinding>
       <binding name="wssMutualCertBinding">
           <security mode="Message">
             <message establishSecurityContext="false" 
                      negotiateServiceCredential="false"
                      clientCredentialType="Certificate"/>
           </security>
         </binding>
        </ws2007HttpBinding> 
   </bindings>
   
   <behaviors>
     <endpointBehaviors>
       <behavior name="MutualCertBehavior">
         <clientCredentials>
           <serviceCertificate>
             <defaultCertificate   
               findValue="6e0e88f36ebb8744d470f62f604d03ea4ebe5094"
               storeLocation="LocalMachine" 
               storeName="My" x509FindType="FindByThumbprint"/>
           </serviceCertificate>
           <clientCertificate     
               findValue="6e0e88f36ebb8744d470f62f604d03ea4ebe5094"
               storeLocation="LocalMachine"
               storeName="My" x509FindType="FindByThumbprint"/>

         </clientCredentials>
       </behavior>
     </endpointBehaviors>
   </behaviors>
 </system.serviceModel>

Figure 20: WCF client configuration using WS-Security with mutual certificates

Notice that we've set the clientCredentialType attribute to Certificate to indicate that the service endpoint requires an X509 certificates as the client authentication mechanism. The specific client and service certificates are detailed in the service behavior included at the end of the configuration file. This configuration is sufficient to instruct the WCF runtime to use WS-Security with mutual certificates. More details about the specific configuration for this security model can be found in this section of the WCF documentation (http://msdn.microsoft.com/en-us/library/ms733102.aspx). Our sample client looks as simple as Figure 21 below:

public void WSSMutualCertTest()
{
  SampleServiceClient service = new SampleServiceClient("wssMutualCert_Client");
  int result = service.Add(11, 11);
}

Figure 21: WCF client code using WS-Security with mutual certificates

At this point, our WCF client is fully interoperable with the sample WSP service created previously. Similar to other scenarios we can achieve WS-Security with mutual certificates using the default configuration bindings with no need of writing additional infrastructure code.

The following section of this paper explores WCF-WSP interoperability beyond WS-Security by exploring some scenarios optimized by the use of WS-SecureConversation.

WS-SecureConversation Interoperability Using WCF and WSP

Overview

In the previous two sections we have explored a couple of the most popular WS-Security interoperability scenarios. From a security standpoint, the WS-Security protocol provides the foundation for protecting single message exchanges between client and services. However, it's very common in real world applications that the interactions between a client and a service result on multiple message exchanges in order to accomplish a specific business function. In the pure WS-Security model, these multiple interactions will require multiple re-authentication round trips on the service side.

WS-SecureConversation is a protocol that attempts to optimize secured multi-message interactions between clients and services avoiding the repetitive exchange of credentials and authentication round trips. Specifically, WS-SecureConversation accomplishes this by allowing clients and services to establish a secured session context with highly optimized keys to protect the messages exchanged during a single session. Figure 22 below provides a high level overview of this concept.

Figure 22: WS-SecureConversation security model

WS-SecureConversation is a very important protocol to improve the performance of WS-Security-based interactions between clients and services.

In their current releases, both WCF and IBM WebSphere Server (WSP) natively support various versions of WS-SecureConversation. In that sense, there are no major challenges in terms of achieving WS-SecureConversation-based interoperability between clients and services implemented in these technology stacks. The following sections deep dive into the techniques that developers can use to implement interoperable web services that leverage WS-SecureConversation on WCF and WSP.

WS-SecureConversation Interoperability Using a WCF service and a WSP Client

Implementing a WCF Service

As explained in previous sections, WCF natively supports WS-SecureConversation as part of various security binding elements. We can instruct the WCF service runtime to configure a service endpoint with WS-SecureConversation by setting the establishSecurityContext attribute to true. This can be accomplished by using a ws2007HttpBinding configuration as illustrated in the following sample, Figure 23.

<system.serviceModel>
 <services>
   <service name="SampleService"   
     behaviorConfiguration="ServiceCredentialsBehavior">
     <endpoint name="wssunt" address="" contract="ISampleService"
               binding="ws2007HttpBinding" 
               bindingConfiguration="wssuntBinding">
       <identity>
         <dns value="Alice"/>
       </identity>
     </endpoint>
   </service>
 </services>
 <bindings>
   <ws2007HttpBinding>
     <binding name="wssuntBinding">
       <security mode="Message"  >
         <message  clientCredentialType="UserName" 
                   establishSecurityContext="true"
                   algorithmSuite="Basic256" 
                   negotiateServiceCredential="false" />
       </security>
     </binding>
   </ws2007HttpBinding>
 </bindings>
 <behaviors>
   <serviceBehaviors>
     <behavior name="ServiceCredentialsBehavior">
       <serviceMetadata httpGetEnabled="true"/>
       <serviceDebug includeExceptionDetailInFaults="true"/>
       <serviceCredentials>
         <userNameAuthentication userNamePasswordValidationMode="Custom"                           
                                 customUserNamePasswordValidatorType=
"Microsoft.ServiceModel.InteropSamples.Extensions.CustomUserNameValidator, Microsoft.ServiceModel.InteropSamples.Extensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
         <serviceCertificate 
                findValue="6e0e88f36ebb8744d470f62f604d03ea4ebe5094"
                storeLocation="LocalMachine" storeName="My"  
                x509FindType="FindByThumbprint"/>
         <clientCertificate>
           <authentication certificateValidationMode="PeerOrChainTrust" />
         </clientCertificate>
       </serviceCredentials>
     </behavior>
     ...
   </serviceBehaviors>
 </behaviors>
</system.serviceModel>

Figure 23: WCF service configuration using WS-SecureConversation

Given that our example bootstraps the WS-SecureConversation message exchange by using username and password credentials we are using a custom username and password validator which validates the username and password credentials provided by the client. This is typically needed in scenarios on which the client and service don’t share a common user repository such as active directory. The following code, Figure 24, illustrates the implementation of the custom validator.

public class CustomUserNameValidator : UserNamePasswordValidator
   {
       public override void Validate(string userName, string password)
       {
           if ("test" != userName || "test" != password)
           {
               throw new ArgumentNullException();
           } 
       }
   }

Figure 24: Custom Username and password validator

The use of a custom validator is important given that is very common to find scenarios on which the WebLogic and WCF environments are using different user repository infrastructures. Using this setting, our WCF service is correctly configured to optimize secure message exchanges using WS-SecureConversation. Let's continue by implementing a WSP client that interacts with our sample service.

Implementing a WebSphere Client

In the current version of IBM WebSphere Application Server (WSP) , you can instruct a web service client to use WS-SecureConversation by simply pointing it to the correct set of WS-SecurityPolicy assertions. In our example, we can achieve that by generating the corresponding WSP proxy from the WCF service implemented in the previous section. As explained throughout this paper, there are several mechanisms for generating this proxy including helper wizards provided by some of the most popular WSP IDEs such as IBM Rational Studio.

To keep things simple, our sample WCF service uses a WS-SecurityPolicy-based policy that is natively supported by WSP and it does not require any additional configuration on the WSP client side. After generating the proxy, we can implement the WSP client using the following code, Figure 25.

public class WS2007HttpBinding_ISampleServiceClient
{
 @WebServiceRef
 private static SampleService sampleService;

   public static void main(String[] args) {
       try {
           sampleService = new SampleService();
           ISampleService iSampleService = sampleService.getWS2007HttpBinding_ISampleService();
           Map<String, Object> requestContext = ((BindingProvider) iSampleService).getRequestContext();
           List credProviders = new ArrayList();
           CredentialProvider untProvider= 
           WS2007HttpBinding_ISampleServiceClient.getUNTCredentialProvider
           ("test", "test") ;
           requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,  
                                                    "service endpoint....");
           CredentialProvider certProvider= 
           WS2007HttpBinding_ISampleServiceClient.getBSTCredentialProvider
           ("wsinterop.jks", "password", "Alice", "password",  
            "wsinterop.jks", "password", "Alice", requestContext);
           credProviders.add(untProvider);
           credProviders.add(certProvider);
           requestContext.put(WSSecurityContext.CREDENTIAL_PROVIDER_LIST, 
                              credProviders);
           int result= iSampleService.add(11,11);
           System.out.println(result);

       } catch (Exception ex) {
           ex.printStackTrace();
       }
   }

Figure 25: WSP WS-SecureConversation client

There is no additional code or configuration required to implement a WSP client that interacts with our sample WCF service using our WS-SecureConversation policy. It is important to notice that the certificates used by our client need to be deployed in a Java Key Store. The Appendicies included in paper illustrate some of the specific mechanisms you can use to create a Key Store that with interoperable X509 certificates.

Similar to the other JAX-WS clients illustrated in this paper, our client will interpret the WS-SecureConversation policy included in the WSDL and configure the runtime accordingly. The complexities of the WS-SecureConversation key exchange are completely hidden by the WSP and WCF runtimes. A similar level of interoperability can be achieved between a WSP service and a WCF client as explained in the following section.

WS-SecureConversation Interoperability Using a WSP service and a WCF Client

Implementing a WSP Service

Implementing an IBM WebSphere Server (WSP) service that uses WS-SecureConversation can be easily done by setting correct policy assertions as part of the service configuration. The current version of WSP includes a large number of preconfigured policies that abstract some of the major web service security scenarios. Additionally, we can use custom policies by deploying the policy files to /WEB-INF/Policies folder of the specific solution or to the default WSP policy store. In our sample scenario, we are using the following WS-SecurityPolicy, Figure 27 below.

<wsp:Policy wsu:Id="WS2007HttpBinding_ISampleService_policy">
<wsp:ExactlyOne>
  <wsp:All>
    <sp:SymmetricBinding xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
    <wsp:Policy>
     <sp:ProtectionToken>
       <wsp:Policy>
        <sp:SecureConversationToken 
        sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
        <wsp:Policy>
        <sp:RequireDerivedKeys/>
        <sp:BootstrapPolicy>
        <wsp:Policy>
        <sp:SignedParts>
         <sp:Body/>
         <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing"/>
         <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing"/>
         <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing"/>
         <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing"/>
         <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing"/>
         <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing"/>
         <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/>
       </sp:SignedParts>
     <sp:EncryptedParts>
   <sp:Body/>
   </sp:EncryptedParts>
  WS-Security with username client policy....
  </wsp:Policy>
 </sp:BootstrapPolicy>
<sp:MustNotSendAmend/>
 </wsp:Policy>
 </sp:SecureConversationToken>
</wsp:Policy>
 </sp:ProtectionToken>
  <sp:AlgorithmSuite>
    <wsp:Policy>
      <sp:Basic256/>
     </wsp:Policy>
    </sp:AlgorithmSuite>
    <sp:Layout>
    <wsp:Policy>
      <sp:Strict/>
     </wsp:Policy>
    </sp:Layout>
    <sp:IncludeTimestamp/>
    <sp:EncryptSignature/>
    <sp:OnlySignEntireHeadersAndBody/>
    </wsp:Policy>
               </sp:SymmetricBinding>
             ...
           </wsp:All>
       </wsp:ExactlyOne>
</wsp:Policy>

Figure 27: WS-SecureConversation policy used by the WSP service (the complete policy can be found in the examples attached to this paprt)

Because of space reasons, we decided not to include the entire policy. It is important to notice that the policy specifies the secure conversation assertion bootstrapped with the WS-Security policy with username credentials used previously in this paper.

After deploying this policy to the WSP server, we can configure our web service to use it by using the @Policy annotations, see Figure 28 below.

@WebService(name = "SampleService_WSSecConv_UNT", serviceName = "SampleService_WSSecConv_UNT",
portName = "SampleService_WSSecConv_UNTSoap12HttpPort")
@BindingType(SOAPBinding.SOAP12HTTP_BINDING)
@Policy(uri = "policy:Wssp1.2-WSSecPolicy.xml")
public class SampleService {
   public SampleService() {
       super();
   }
   
   public int Add(int param1, int param2)
   {
       return param1 + param2;
       }
}

Figure 28: WSP Service configured with a WS-SecureConversation policy

At this point, we can deploy our sample service to a WSP instance so that it can be accessed by its clients. The following section details how to implement a WCF client that interacts with our WSP service.

Implementing a WCF client

Implementing a WCF client that interoperates with our WebSphere (WSP) service using WS-SecureConversation is mostly a matter of using the correct ws2007HttpBinding configuration as illustrated in the following code, Figure 29 below.

<system.serviceModel>
   <bindings>
       <ws2007HttpBinding>
         <binding name="wssecBinding">
           <security mode="Message"  >
             <message  clientCredentialType="UserName" 
                       establishSecurityContext="true"
                       algorithmSuite="Basic256" 
                       negotiateServiceCredential="false" />
           </security>
         </binding>
       </ws2007HttpBinding>
   </bindings>
   <client>
     <endpoint address="service endpoint..."
         binding="ws2007HttpBinding" bindingConfiguration="wssecBinding"
         contract="ISampleService" name="wssuntClient" 
         behaviorConfiguration="SecBehavior">
       <identity>
         <dns value="Alice"/>
       </identity>
     </endpoint>
   </client>
   <behaviors>
     <endpointBehaviors>
       <behavior name="SecBehavior">
           <clientCredentials>
             <serviceCertificate>
               <defaultCertificate   
                  findValue="6e0e88f36ebb8744d470f62f604d03ea4ebe5094"
                  storeLocation="LocalMachine" storeName="My" 
                  x509FindType="FindByThumbprint"/>
               <authentication certificateValidationMode="None"/>
             </serviceCertificate>
           </clientCredentials>
       </behavior>
     </endpointBehaviors>
   </behaviors>
 </system.serviceModel>

Figure 29: WCF client configuration

It is important to notice that the binding configuration associated to the client endpoint has the establishSecurityContext attribute set to true. This setting instructs the WCF client runtime to use WS-SecureConversation to optimize the exchange of security keys.

The only remaining task is to set the appropriate username and password credentials used to bootstrap the WS-SecureConversation message exchange. Given that these types of credentials can't be specified via configuration, we need to write the following code, see Figure 30 below.

public void WSSUserNameAndPasswordTest()
{
 SampleServiceClient service = new SampleServiceClient("wssecClient");
 service.ClientCredentials.UserName.UserName = "test";
 service.ClientCredentials.UserName.Password= "test";
 int result = service.Add(11, 11);
}

Figure 30: WCF Client that uses the WS-SecureConversation configuration

It’s important to notice that we are only hardcoding the username and password credentials for the simplicity of the example. In real world scenarios, it’s most likely that these credentials will be extracted from a secure repository. At this point, there are no additional steps required to implement a WCF client that interoperates with our sample WebSphere service using WS-SecureConversation. Typically, real world services use WS-SecureConversation bootstrapped with a WS-Security profile as we did in our example. In that sense, it important to rely on an interoperable WS-Security configuration when optimizing secure sessions using WS-SecureConversation. Despite the level of complexity of the secure conversation protocol, you can see how simple it is to achieve seamless interoperability between WCF and WSP services and clients.

WS-Trust Interoperability etween Windows Identity Foundation and IBM WebSphere

Until now, the scenarios explored in this paper are focused on point-to-point in which a client interacts with a web service using certain WS-* security protocols. The security models explored as part of these scenarios enforce important security capabilities such as confidentiality, message protection, authentication, etc. Most of these capabilities rely on security tokens issued by the different web service technology stacks.

In medium or large service oriented solutions it is very common to centralize features such as authentication or token issuance using a separate service. Using this model, both clients and services can TRUST the identity information received from a central service. This type of service is formally known as Security Token Service (STS) and it represents a broker that centralizes the secure interactions between a client and a service. Figure 31 below illustrates this type of brokered security model.

Figure 31: Brokered security model based on WS-Trust

As the previous figure reflects, the client needs to obtain a secure token from the STS before communicating with the service. Both service and client trust the identity information issued by the STS. The message exchanges between clients, STSs and services that are required to enable this type of scenario have been formalized in a series of extensions to WS-Security known as WS-Trust.

Even though WCF fully supports the latest versions of the WS-Trust protocol, is still slightly complex to implement some of its components such a STS. In order to address these challenges, Microsoft recently released the first version of the Windows Identity Foundation (WIF) which provides an very simple model for implementing brokered security infrastructure based on WS-Trust.

Similarly, the current version of IBM WebSphere Server (WSP) also supports a subset of the WS-Trust specification which, under certain constraints, can interact with WIF. It’s important to notice that brokered security scenarios entail two fundamental interoperability points: the client-STS interaction and the client-service interaction. While the latter of these models is based on the WS-Trust protocol, the interactions between the client application and the STS can fully leverage some of the security models explored on this paper. The interoperability between WSP and WIF presents some challenges but it is certainly achievable using the extensibility mechanisms available on both identity stacks.

Conclusion

This paper has covered a series of web service security interoperability scenarios between the latest versions of Windows Communication Foundation (WCF), Windows Identity Foundation (WIF) and IBM WebSphere Server (WSP). The current versions of WCF and WSP provide seamless interoperability for the WS-Security and WS-SecureConversation specifications. Even though brokered security interoperability between WCF and WSP using WS-Trust is still challenging, developers can leverage the extensibility mechanisms of WCF and WIF to mitigate some of the existing interoperability challenges.


About the author: Jesus Rodriguez is the Co-founder and Chief Architect of Tellago, Inc, an Enterprise Architecture consulting firm specializing in large-scale SOA projects. Jesus is also Co-Founder and Chief Architect of Tellago Studios, a company that focuses on implementing innovative enterprise software solutions including the popular WCF management registry: SO-Aware. He is also a Microsoft BizTalk Server MVP, an Oracle ACE and one of a few Architects worldwide to be a member of the Microsoft Connected Systems Advisor team. As a member, Jesus has been selected to participate in a variety of Software Design Reviews with different Microsoft’s Product Teams. Jesus is an active contributor to the .NET and J2EE communities and an internationally recognized speaker and author. He is a prolific blogger on all subjects related to integration and has a true passion for technology. Contact Jesus at jesus.rodriguez@tellago.com or through his blog at http://weblogs.asp.net/gsusx.

Appendix A: Using Windows X509 Certificates with IBM WebSphere Server

The different examples explored in this white paper require the use of X509 certificates to enable certain security capabilities such as authentication or message protection. When implementing WS-* security interoperability scenarios between WCF and IBM WebSphere (WSP), it is very important to correctly deploy Windows' X509 certificates to the WSP instance so that they can be used by web services and clients.

WSP leverages a Java key store as the mechanism for storing X509 certificates that can be used as part of WS-Security based interactions. We can manage this type of key store by using the keytool certificate management utility included in the Java standard runtime (j2se). Specifically, we can use the following command to create a new key store:

keytool -genkey -alias mydomain -keyalg RSA -keystore wsinterop.jks

We can import a Windows certificate with its private key (.pfx format) into a Java key store by using the following command:

keytool -importkeystore -srckeystore cert.pfx -destkeystore wsinterop.jks

-srcstoretype pkcs 12 -deststoretype jks

 

We can also import certificates without their private key using the following command:

keytool -import -trustcacerts -alias root -file cert.crt -keystore wsinterop.jks

At any time we can list the certificates stores in Java key store by using the following command:

keytool -list -v -keystore wsinterop.jks

Additionally, we can also delete a certificate from the key store by using the following command:

keytool -delete -alias mycert -keystore wsinterop.jks

In case we need more sophisticated migrations between Windows and Java certificates, we can consider using a toolset like OpenSSL (http://www.openssl.org/) which enables a large variety of certificate transformations.

Appendix B: Specifying key store settings for bindings configuration

The WS-Security policy uses keys to digitally sign messages or encrypting your Web service messages. As part of configuring a binding for the WS-Security policy, you must provide information about the files in which these keys are stored.

To specify settings for your key stores:

  1. In the Client Side Policy Set Attachment wizard, select the WSSecurity policy type in the Bindings Configuration table; then click Configure.
  2. In the WS-Security binding configuration window, the Digital Signature Configuration tab and the XML Encryption Configuration tab both contain areas where you can specify settings for outbound and inbound messages, Click the Key Store Settings button in the area where you want to specify key store settings.
  3. In the Key Store Settings Dialog window:
    1. Type the path and name of the keystore file that you received from the Web service provider in the Keystore Path field, or select the file by using the Browse button.
    2. Type the password for your keystore in the Keystore Password field.
    3. Select the type of your key store from the Keystore Type list.
    4. Type the alias for your key in the Key Alias field.
    5. Type the password for your key in the Key Password field.
  4. Click OK.