Invoking a WCF service secured with Kerberos via WSO2 ESB

1. Set up WCF service secured with Kerberos - explained in this blog post.

2. Set up the WSO2 ESB to work with Kerberos - explained in this blog post - follow the steps 0,1,2,3 and 4.

3. Create a resource in the WSO2 ESB - embedded registry with the following content - this is the security policy we will be applying to the out going messages from the ESB to the WCF service.

In this example, I created a Resource Collection called 'policies' under /_system/governance and created a Resource called krbpolicy with the following content under /_system/governance/policies.

So, my security policy from the registry is /_system/governance/policies/krbpolicy
<?xml version="1.0" encoding="UTF-8"?>
<wsp:Policy wsu:Id="kerberossignandencrypt"
 xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
 xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
 <wsp:ExactlyOne>
  <wsp:All>
   <sp:SymmetricBinding
    xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
    <wsp:Policy>
     <sp:ProtectionToken>
      <wsp:Policy>
       <sp:KerberosToken
        sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
        <wsp:Policy>
         <sp:WssKerberosV5ApReqToken11 />
        </wsp:Policy>
       </sp:KerberosToken>
      </wsp:Policy>
     </sp:ProtectionToken>
     <sp:AlgorithmSuite>
      <wsp:Policy>
       <sp:Basic256 />
      </wsp:Policy>
     </sp:AlgorithmSuite>
     <sp:Layout>
      <wsp:Policy>
       <sp:Lax />
      </wsp:Policy>
     </sp:Layout>
     <sp:IncludeTimestamp />
     <sp:OnlySignEntireHeadersAndBody />
    </wsp:Policy>
   </sp:SymmetricBinding>
   <sp:SignedParts
    xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
    <sp:Body />
   </sp:SignedParts>
   <sp:Wss11 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
    <sp:Policy>
     <sp:MustSupportRefKeyIdentifier />
     <sp:MustSupportRefIssuerSerial />
     <sp:MustSupportRefThumbprint />
     <sp:RequireSignatureConfirmation />
    </sp:Policy>
   </sp:Wss11>
   <sp:Trust10 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
    <wsp:Policy>
     <sp:RequireClientEntropy />
     <sp:RequireServerEntropy />
     <sp:MustSupportIssuedTokens />
    </wsp:Policy>
   </sp:Trust10>
   <rampart:RampartConfig xmlns:rampart="http://ws.apache.org/rampart/policy">
    <rampart:timestampPrecisionInMilliseconds>true
    </rampart:timestampPrecisionInMilliseconds>
    <rampart:timestampTTL>300</rampart:timestampTTL>
    <rampart:timestampMaxSkew>300</rampart:timestampMaxSkew>
    <rampart:kerberosConfig>
     <rampart:property name="client.principal.name">client</rampart:property>
     <rampart:property name="client.principal.password">1qaz2wsx$
     </rampart:property>
     <rampart:property name="service.principal.name">service/myserver@WSO2.COM
     </rampart:property>
     <rampart:property name="java.security.auth.login.config">jaas.conf
     </rampart:property>
     <rampart:property name="javax.security.auth.useSubjectCredsOnly">true</rampart:property>
     <rampart:property name="kdc.des.aes.factor">4</rampart:property>
     <rampart:property name="java.security.krb5.conf">/Users/prabath/clients/wso2esb-3.0.1/repository/conf/krb.conf
     </rampart:property>
    </rampart:kerberosConfig>
   </rampart:RampartConfig>
  </wsp:All>
 </wsp:ExactlyOne>
</wsp:Policy>
In the policy we have to set the absolute path to the krb.conf - at the same time we need to set the username and password of the client who invokes the WCF service appropriately - and this account should be in the Active Directory.

4. Now create a proxy service - and in the InSequence - in the Endpoint pointing to the WCF service, enable security and pick the security policy we set before, from the registry.

The endpoint configuration in the synapse config will look like,
<endpoint name="endpoint_urn_uuid_81768417D4430798591291451112900558002-585115135">
                <address uri="http://192.168.2.13/EchoServices/EchoService.svc">
                    <enableSec policy="gov:/policies/krbpolicy"/>
                </address>
</endpoint>
5. Also in the InSequence we need to add a Property mediator and set the following.
<property name="PRESERVE_WS_ADDRESSING" value="true"/>
6. Now in the OutSequence - we need to remove the Security Header coming from the WCF service before the Send mediator in the OutSequence - you can do it with a Header mediator.
<header xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" name="wsse:Security" action="remove"/>
7. Also in the OutSequence we need to add a Property mediator and set the following.
<property name="disableAddressingForOutMessages" value="true" scope="axis2"/>
These two properties [5 & 7] are needed if the back end service is WCF and it is secured using WS-Security and ESB is acting as a passthrough. When communicating with WCF, wsa:to should point to WCF service endpoint (In axis2, it can can point to some other place, still axis2 will dispatch correctly using URL). For the pass through with security case, client should sign wsa:headers (WS-Security requirement) and hence wsa:to cannot be changed by ESB (violation of signature); Hence, the requirement for "preserve addressing". When the response comes from WCF->ESB, ESB adds addressing header regardless of whether the original message (from WCF) has addressing or not. In above case, since wsa:headers of request is signed by client, response from WCF will contain a signed wsa headers. If ESB adds one more set of addressing headers, then it will be violating protocol. Hence the requirement for "disable addressing for out messages"

8. Now your InSquence will like,
<inSequence>
                <property name="PRESERVE_WS_ADDRESSING" value="true" scope="default" type="STRING"/>
            </inSequence>
9. OutSequence will look like,
<outSequence>
                <property name="disableAddressingForOutMessages" value="true" scope="axis2"/>
                <header xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" name="wsse:Security" action="remove"/>
                <send/>
            </outSequence>
10. That's it :)