WSIT: JKS relative filepath

1.4k views Asked by At

When creating a web service server using Netbeans, Maven, Metro and Tomcat, how can I use relative filepaths in the wsit configuration?

For example, I have this line inside the wsit file:

<sc:KeyStore wspp:visibility="private" location="SERVER_KeyStore.jks" type="JKS" storepass="*****" alias="*****"/>

where should I put the jks file so it matches that location?

2

There are 2 answers

0
Jose Antonio On BEST ANSWER

Finally, I found the answer.

when providing the keystore/trustore name and location in the wsit-*.xml files, please note that they'll be loaded as resources scanning the META-INF directory in your package (WEB-INF/classes/META-INF when using war packages on JBoss Application Server 5).

from JBossWS - Stack Metro User Guide

In my case that means adding a META-INF folder to my resources folder and add <include>**/*.jks</include> to the pom file.

0
dmitry On

I saw some number of questions for wsit security configuration, most of them deal with externalizing SSL configuration, rather than hardcoding into wsdl file. Just because there may be development and production environment, and all in all hardcoded configuration is bad anyway. I spend several days with this issue and found only some (often monstrous) hints here in stackoverflow and various other forums. But the solution turned to be not so complex indeed. I just leave it here for someone (it matches also original question, because it will allow having jks anywhere, also having external config file as well).

Say, you have wsit policy in your wsdl files like this:

<wsp1:Policy wsu:Id="MyBinding_IWebServicePolicy">
    <wsp1:ExactlyOne>
        <wsp1:All>
            <sc:KeyStore wspp:visibility="private" type="JKS" storepass="pass" alias="some-alias" keypass="pass" location="keystore.jks"/>
            <sc:TrustStore wspp:visibility="private" type="JKS" peeralias="other-alias" storepass="pass" location="truststore.jks"/>
        </wsp1:All>
    </wsp1:ExactlyOne>
</wsp1:Policy>

You need to use CallbackHandler instead.

Adjusted policy:

<wsp1:Policy wsu:Id="MyBinding_IWebServicePolicy">
    <wsp1:ExactlyOne>
        <wsp1:All>
            <sc:KeyStore wspp:visibility="private" callbackHandler="com.my.KeyStoreHandler"/>
            <sc:TrustStore wspp:visibility="private" callbackHandler="com.my.TrustStoreHandler"/>
        </wsp1:All>
    </wsp1:ExactlyOne>
</wsp1:Policy>

And handler might look like this (I use scala, but you may translate this to java easily):

import javax.security.auth.callback.{ CallbackHandler => ICallbackHandler, Callback }
import com.sun.xml.wss.impl.callback.{ KeyStoreCallback, PrivateKeyCallback }
import java.security.{ PrivateKey, KeyStore }
import java.io.FileInputStream

abstract class CallbackHandler extends ICallbackHandler {
  def conf: Config // getting external configuration

  def handle(callbacks: Array[Callback]): Unit = callbacks foreach {
    // loads the keystore
    case cb: KeyStoreCallback =>
      val ks = KeyStore.getInstance(conf.getString("type"))
      val is = new FileInputStream(conf.getString("file"))
      try ks.load(is, conf.getString("store-password").toCharArray) finally is.close()
      cb.setKeystore(ks)

    // loads private key
    case cb: PrivateKeyCallback =>
      cb.setAlias(conf.getString("alias"))
      cb.setKey(cb.getKeystore.getKey(conf.getString("alias"), conf.getString("key-password").toCharArray).asInstanceOf[PrivateKey])

    // other things
    case cb => // I didn't need anything else, but just in case
  }
}

class TrustStoreHandler extends CallbackHandler {
  lazy val conf = getMyTrustStoreConfig
}

class KeyStoreHandler extends CallbackHandler {
  lazy val conf = getMyKeyStoreConfig
}

In java just use if (cb isinstanceof Class) instead of case cb: Class =>, the other code is practically java without semicolons.