使用 Netbeans、Maven、Metro 和 Tomcat 创建 Web 服务服务器时,如何在 wsit 配置中使用相对文件路径?
例如,我在 wsit 文件中有这一行:
<sc:KeyStore wspp:visibility="private" location="SERVER_KeyStore.jks" type="JKS" storepass="*****" alias="*****"/>
我应该把 jks 文件放在哪里,以便它匹配那个位置?
最后,我找到了答案。
在 wsit-*.xml 文件中提供 keystore/trustore 名称和位置时,请注意它们将作为资源加载,扫描包中的 META-INF 目录(使用 war 时为 WEB-INF/classes/META-INF JBoss 应用服务器 5 上的软件包)。
在我的情况下,这意味着将 META-INF 文件夹添加到我的资源文件夹并添加<include>**/*.jks</include>
到 pom 文件中。
我看到了一些关于wsit
安全配置的问题,其中大多数涉及外部化 SSL 配置,而不是硬编码到 wsdl 文件中。只是因为可能有开发和生产环境,而且无论如何硬编码配置都是不好的。我在这个问题上花了几天时间,在 stackoverflow 和其他各种论坛中只发现了一些(通常是可怕的)提示。但解决方案确实没有那么复杂。我只是把它留给某人(它也符合原始问题,因为它允许在任何地方拥有 jks,也有外部配置文件)。
比如说,您的 wsdl 文件中有 wsit 策略,如下所示:
<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>
你需要CallbackHandler
改用。
调整后的政策:
<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>
处理程序可能看起来像这样(我使用 scala,但您可以轻松地将其转换为 java):
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
}
在 java 中只需使用if (cb isinstanceof Class)
而不是case cb: Class =>
,其他代码实际上是没有分号的 java。