Jax-WSパスワードタイプPasswordText
質問
SOAPリクエストをテストするための単純なコマンドラインJava Jax-WSアプリを持っていますが、サーバーはパスワードタイプがパスワードテキストであることを期待しており、これを設定する方法に困惑しています...
コードはそうです:
@WebServiceRef
private static final HelloService helloService = new HelloService(url, new QName(
URL, "HelloService"));
public static void main(final String... args) {
try {
final HelloPort helloPort = helloService.getHelloPort();
final BindingProvider hB = ((BindingProvider) helloPort);
hB.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
END_POINT_ADDRESS);
hB.getRequestContext().put(BindingProvider.USERNAME_PROPERTY,
USERNAME);
hB.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY,
PASSWORD);
...
SOAP-UIを使用してリクエストをテストしたので、それが機能していることがわかりました。パスワードタイプの設定に関するヘルプをいただければ幸いです。
ありがとう。
解決
これにより、基本的なHTTP認証のユーザー名とパスワードが設定されます。 Soapuiでテストした場合、リクエストの詳細ペインの「WSS-Passwordタイプ」である「PasswordText」値が「WSS-Passwordタイプ」であると推測しています。これにより、HTTPセキュリティではなくWSSセキュリティが設定されます。
Java6のJax-WSを使用すると、SOAPHANDLERを取り付けて、WSS-USERTOKENOKEDをSOAPヘッダーに注入する必要があります。ネットの周りにはたくさんのビットとボブがありますが、投稿への1つのリンクが見つからなかったので、代わりにあなたを動かすためのコードをいくつか紹介します...
ハンドラーを追加するには、次のようなものが必要です。
final Binding binding = ((BindingProvider) servicePort).getBinding();
List<Handler> handlerList = binding.getHandlerChain();
if (handlerList == null)
handlerList = new ArrayList<Handler>();
handlerList.add(new SecurityHandler());
binding.setHandlerChain(handlerList); // <- important!
その後、セキュリティハンドラークラスが行為を行います。ハンドラーは一般的なものであり、成功したメッセージと障害の両方で呼び出されますが、おそらくもっと重要なことには、彼らは呼ばれます 両方とも メッセージの指示 - 発信リクエストのために、そして再び着信のために。発信メッセージのみを処理したいです。だからあなたは次のようなものが必要です:
public final class SecurityHandler implements SOAPHandler<SOAPMessageContext> {
...
@Override
public boolean handleMessage(final SOAPMessageContext msgCtx) {
// Indicator telling us which direction this message is going in
final Boolean outInd = (Boolean) msgCtx.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
// Handler must only add security headers to outbound messages
if (outInd.booleanValue()) {
try {
// Get the SOAP Envelope
final SOAPEnvelope envelope = msgCtx.getMessage().getSOAPPart().getEnvelope();
// Header may or may not exist yet
SOAPHeader header = envelope.getHeader();
if (header == null)
header = envelope.addHeader();
// Add WSS Usertoken Element Tree
final SOAPElement security = header.addChildElement("Security", "wsse",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
final SOAPElement userToken = security.addChildElement("UsernameToken", "wsse");
userToken.addChildElement("Username", "wsse").addTextNode("MyWSSUsername");
userToken.addChildElement("Password", "wsse").addTextNode("MyWSSPassword");
} catch (final Exception e) {
LOG.error(e);
return false;
}
}
return true;
}
...
// Other required methods on interface need no guts
}
ここでいくつかの仮定をしましたが、うまくいけばあなたを動かすでしょう!
敬具。
他のヒント
Soaphandlerインターフェイスを実装すると、メソッドmsgctx.getMessage()がXML全体をレンダリングし、大きなファイルを使用している場合はメモリエラーが発生します。 Jax-WSクライアントでusernametoken認証でテストしました。
String SECURITY_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
String PASSWORD_TYPE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText";
String AUTH_PREFIX = "wss";
MyService service = new MyService();
MyServicePort port = service.getMyServicePort();
try {
SOAPFactory soapFactory = SOAPFactory.newInstance();
SOAPElement security = soapFactory.createElement("Security", AUTH_PREFIX, SECURITY_NS);
SOAPElement uToken = soapFactory.createElement("UsernameToken", AUTH_PREFIX, SECURITY_NS);
SOAPElement username = soapFactory.createElement("Username", AUTH_PREFIX, SECURITY_NS);
username.addTextNode("username");
SOAPElement pass = soapFactory.createElement("Password", AUTH_PREFIX, SECURITY_NS);
pass.addAttribute(new QName("Type"), PASSWORD_TYPE);
pass.addTextNode("password");
uToken.addChildElement(username);
uToken.addChildElement(pass);
security.addChildElement(uToken);
Header header = Headers.create(security);
((WSBindingProvider) port).setOutboundHeaders(header);
// now, call webservice
} catch (SOAPException ex) {
ex.printStackTrace();
}
編集: JREから「Rt.jar」をClassPathに追加する必要があります。