Monday, January 18, 2016

Jboss Fuse / Apache Camel - How to enable ws-security? (3/250 - 2016)


Dependencies to be added in pom.xml
<dependency>
   <groupId>org.apache.wss4j</groupId>
   <artifactId>wss4j-bindings</artifactId>
   <version>2.0.3</version>
  </dependency>
  <dependency>
   <groupId>org.apache.wss4j</groupId>
   <artifactId>wss4j-policy</artifactId>
   <version>2.0.3</version>
  </dependency>
  <dependency>
   <groupId>org.apache.wss4j</groupId>
   <artifactId>wss4j-ws-security-common</artifactId>
   <version>2.0.3</version>
  </dependency>
  <dependency>
   <groupId>org.apache.wss4j</groupId>
   <artifactId>wss4j-ws-security-dom</artifactId>
   <version>2.0.3</version>
  </dependency>
  <dependency>
   <groupId>org.apache.wss4j</groupId>
   <artifactId>wss4j-ws-security-policy-stax</artifactId>
   <version>2.0.3</version>
  </dependency>
  <dependency>
   <groupId>org.apache.wss4j</groupId>
   <artifactId>wss4j-ws-security-stax</artifactId>
   <version>2.0.3</version>
  </dependency>


Features to be installed in Fuse:

features:install wss4j
features:install cxf-wssecurity


Update Bluerpint with the code place- 
  <http:conduit name="https://.*/.*">
  <http:tlsClientParameters disableCNCheck="true">
   <sec:trustManagers>
    <sec:keyStore type="JKS" file="etc/uatesb.jks" password="password" />
   </sec:trustManagers>
   <sec:keyManagers keyPassword="password">
    <sec:keyStore type="JKS" file="etc/uatesb.jks" password="password" />
   </sec:keyManagers>

   <sec:cipherSuitesFilter>
    <sec:include>.*_EXPORT_.*</sec:include>
    <sec:include>.*_EXPORT1024_.*</sec:include>
    <sec:include>.*_WITH_DES_.*</sec:include>
    <sec:include>.*_WITH_AES_.*</sec:include>
    <sec:include>.*_WITH_NULL_.*</sec:include>
    <sec:exclude>.*_DH_anon_.*</sec:exclude>
   </sec:cipherSuitesFilter>
  </http:tlsClientParameters>
  <http:client AutoRedirect="true" Connection="Keep-Alive" />
 </http:conduit>


Based on the requirement add Inbound / Outbound Interceptors within the consumer / producer endpoints.

<cxf:inInterceptors>
 <bean id="wss4jInInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
  <property name="properties">
   <map>
    <entry key="passwordType" value="PasswordText" />
    <entry key="action" value="UsernameToken" />
    <entry key="passwordCallbackRef">
     <bean class="com.dummy.handler.PasswordCallback">
      <property name="passwordMap">
       <map>
        <entry key="${datapower.user.id}" value="${datapower.user.password}" />
        <entry key="${esb.user.id}" value="${esb.user.password}" />
       </map>
      </property>
     </bean>
    </entry>
   </map>
  </property>
 </bean>
</cxf:inInterceptors>



<cxf:outInterceptors>
 <bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
  <property name="properties">
   <map>
    <entry key="user" value="wesb" />
    <entry key="passwordCallbackRef">
    <bean id="passwordCallback" class="com.dummy.handler.PasswordCallback">
     <property name="passwordMap">
      <map>
       <entry key="${datapower.user.id}" value="${datapower.user.password}" />
       <entry key="${esb.user.id}" value="${esb.user.password}" />
      </map>
     </property>
    </bean>
    </entry>
    <entry key="action" value="UsernameToken Timestamp" />
    <entry key="passwordType" value="PasswordDigest" />
    <entry key="mustUnderstand" value="${secureEnable}" />
   </map>
  </property>
 </bean>
</cxf:outInterceptors>



The PasswordCallback Impl

public class PasswordCallback implements CallbackHandler {

 private static Logger logger = Logger.getLogger(PasswordCallback.class);
 private Map<String, String> passwordMap;

 public Map<String, String> getPasswordMap() {
  return passwordMap;
 }

 public void setPasswordMap(Map<String, String> passwordMap) {
  this.passwordMap = passwordMap;
 }

 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
  WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
  if (pc.getIdentifier() != null && passwordMap != null) {
   if ("wesb".equals(pc.getIdentifier())) {
    try {
     pc.setPassword((DummyEncryptDecrypter.decrypt(passwordMap.get(pc.getIdentifier()))));
    } catch (DummyCipherException e) {

     e.printStackTrace();
     logger.error("Error in decrypt password for id " + pc.getIdentifier());
     throw new UnsupportedCallbackException(null, "Error in decrypt password for id " + pc.getIdentifier());
    }
   } else {
    pc.setPassword(passwordMap.get(pc.getIdentifier()));
   }
  }
 }
}



DummyEncryptDecrypter

public class DummyEncryptDecrypter {

 Cipher cipher;

 private final static String IV = "password12345678";
 private final static String AES_CBC = "AES/CBC/PKCS5Padding";
 
 private static Logger logger = Logger.getLogger(DummyEncryptDecrypter.class);
 
 static SecretKeySpec key = new SecretKeySpec(IV.getBytes(), "AES");

 /**
  * Decrypt
  * 
  * @param cipherText
  * @return
  * @throws DummyCipherException
  */
 public static  String decrypt(String cipherText) throws DummyCipherException  {
  if(cipherText==null){
   return "";
  }
  AlgorithmParameterSpec paramSpec = new IvParameterSpec(
    IV.getBytes());

  Cipher cipher = null;
  byte[] output = null;
  byte[] decrypted = null;
  try {
   cipher = Cipher.getInstance(AES_CBC);
   cipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
   output = new BASE64Decoder().decodeBuffer(cipherText);
   decrypted = cipher.doFinal(output);
  } catch (Exception e) {
   logger.error("Exception while decrypt ");

   throw new DummyCipherException(e.getMessage(), e);
  }
  String palintText = new String(decrypted);
  return palintText;
 }

 /**
  * Encrypt
  * 
  * @param painText
  * @return
  * @throws DummyCipherException
  */
 public static String encrypt(String painText) throws DummyCipherException {

  if(painText==null){
   return "";
  }
  AlgorithmParameterSpec paramSpec = new IvParameterSpec(
    IV.getBytes());

  Cipher cipher = null;
  byte[] ecrypted = null;
  String output = null;

  try {
   cipher = Cipher.getInstance(AES_CBC);
   cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
   ecrypted = cipher.doFinal(painText.getBytes());
   output = new BASE64Encoder().encode(ecrypted);
  } catch (Exception e) {
   logger.error("Exception while encrypting the string "+e.getMessage());
   throw new DummyCipherException(e.getMessage(), e);
  } 
  return output;

 }
 
 public static void main(String arg[]) throws DummyCipherException{
  String s = "xxxxxxxxxx";
  System.out.println(new DummyEncryptDecrypter().decrypt(s));
  System.out.println(new DummyEncryptDecrypter().encrypt("password"));
 }
}


DummyCipherException 
public class DummyCipherException extends Exception {

 private static final long serialVersionUID = 1L;
 public DummyCipherException(String message) {
  super(message);
 }
 public DummyCipherException(String message, Exception e) {
  super(message, e);
 }
}

Configuration File
datapower.user.password=xxxx
datapower.user.id=xxxx
keystore.password=xxxx
secureEnable=false
esb.user.id=xxxx
esb.user.password=xxxx


No comments: