Java JAX-WS 密码类型 PasswordText
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3096183/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JAX-WS Password Type PasswordText
提问by marktucks
I've got a simple command line Java JAX-WS app to test a SOAP request, but the server is expecting the Password Type to be PasswordText and I'm stumped on how to set this...
我有一个简单的命令行 Java JAX-WS 应用程序来测试 SOAP 请求,但服务器期望密码类型为 PasswordText 并且我很难过如何设置它...
The code looks like so:
代码如下所示:
@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);
...
I've tested the request using SOAP-UI so I know it's working. Any help on setting the password type would be appreciated.
我已经使用 SOAP-UI 测试了请求,所以我知道它正在工作。任何有关设置密码类型的帮助将不胜感激。
Thanks.
谢谢。
采纳答案by SimonB
That will set the username and password for Basic HTTP authentication. If you've tested it in SoapUI, I'm guessing the 'PasswordText' value you speak of is the 'WSS-Password Type' in the request details pane. That sets WSS security, not HTTP security.
这将为基本 HTTP 身份验证设置用户名和密码。如果您已经在 SoapUI 中对其进行了测试,我猜您所说的“PasswordText”值是请求详细信息窗格中的“WSS-Password Type”。这设置了 WSS 安全性,而不是 HTTP 安全性。
With JAX-WS in Java6 you need to attach a SOAPHandler to inject the WSS-Usertoken into the SOAP Header. There are plenty of bits and bobs about this round the net, but I couldn't find one single link to post, so here's some code instead to get you going...
使用 Java6 中的 JAX-WS,您需要附加一个 SOAPHandler 以将 WSS-Usertoken 注入到 SOAP Header 中。网上有很多关于这一轮的点点滴滴,但我找不到一个单独的链接来发布,所以这里有一些代码可以让你继续前进......
To add a handler you need something like:
要添加处理程序,您需要类似的东西:
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!
Then the SecurityHandler class will do the deed. Handlers are general things and get called for both successful messages and for faults, but perhaps more importantly they get called in bothmessage directions - for the outgoing request and then again for the incoming response. You only want to handle outgoing messages. So you'll need something like:
然后 SecurityHandler 类将执行此操作。处理程序是通用的东西,成功的消息和错误的消息都会被调用,但也许更重要的是,它们在两个消息方向上都会被调用- 对于传出的请求,然后又是针对传入的响应。您只想处理传出的消息。所以你需要这样的东西:
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
}
I've made a few assumptions here, but hopefully it'll get you going!
我在这里做了一些假设,但希望它能让你前进!
Kind regards.
亲切的问候。
回答by cleison
If you implement SOAPHandler interface, the method msgCtx.getMessage() will render the entire XML, and if you are working with big files you will have Out of Memory errors. I tested with UsernameToken authentication on JAX-WS client and it works:
如果您实现 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();
}
Edit:You should add the "rt.jar" from jre to classpath.
编辑:您应该将 jre 中的“rt.jar”添加到类路径。