我在Glassfish之上创建了一个JAX-WS Web服务,它需要基本的HTTP身份验证。
现在我想为该Web服务创建一个独立的Java应用程序客户端,但我不知道如何传递用户名和密码。
它适用于Eclipse的Web Service资源管理器,并检查我发现的电线:
POST /SnaProvisioning/SnaProvisioningV1_0 HTTP/1.1
Host: localhost:8080
Content-Type: text/xml; charset=utf-8
Content-Length: 311
Accept: application/soap+xml, application/dime, multipart/related, text/*
User-Agent: IBM Web Services Explorer
Cache-Control: no-cache
Pragma: no-cache
SOAPAction: ""
Authorization: Basic Z2VybWFuOmdlcm1hbg==
Connection: close
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://ngin.ericsson.com/sna/types/v1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<q0:listServiceScripts/>
</soapenv:Body>
</soapenv:Envelope>
如何使用java代码在此“Authorization”标头中传递用户名和密码?它是哈希还是类似的东西?算法是什么?
如果没有安全性,我有一个独立的Java客户端:
SnaProvisioning myPort = new SnaProvisioning_Service().getSnaProvisioningV10Port();
myPort.listServiceScripts();
答案 0 :(得分:62)
用于基本身份验证的JAX-WS方式是
Service s = new Service();
Port port = s.getPort();
BindingProvider prov = (BindingProvider)port;
prov.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "myusername");
prov.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "mypassword");
port.call();
答案 1 :(得分:44)
事实证明,有一种简单,标准的方式来实现我想要的目标:
import java.net.Authenticator;
import java.net.PasswordAuthentication;
Authenticator myAuth = new Authenticator()
{
@Override
protected PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication("german", "german".toCharArray());
}
};
Authenticator.setDefault(myAuth);
没有自定义“sun”类或外部依赖项,也没有手动编码任何内容。
我知道BASIC安全性不是很安全,但我们也使用HTTPS。
答案 2 :(得分:9)
对于Axis2
客户端,这可能会有所帮助
...
serviceStub = new TestBeanServiceStub("<WEB SERVICE URL>"); // Set your value
HttpTransportProperties.Authenticator basicAuthenticator = new HttpTransportProperties.Authenticator();
List<String> authSchemes = new ArrayList<String>();
authSchemes.add(Authenticator.BASIC);
basicAuthenticator.setAuthSchemes(authSchemes);
basicAuthenticator.setUsername("<UserName>"); // Set your value
basicAuthenticator.setPassword("<Password>"); // Set your value
basicAuthenticator.setPreemptiveAuthentication(true);
serviceStub._getServiceClient().getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.AUTHENTICATE, basicAuthenticator);
serviceStub._getServiceClient().getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.CHUNKED, "false");
...
答案 3 :(得分:4)
如果您正在为客户端使用JAX-WS实现,例如Metro Web Services,则以下代码显示如何在HTTP标头中传递用户名和密码:
MyService port = new MyService();
MyServiceWS service = port.getMyServicePort();
Map<String, List<String>> credentials = new HashMap<String,List<String>>();
credentials.put("username", Collections.singletonList("username"));
credentials.put("password", Collections.singletonList("password"));
((BindingProvider)service).getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS, credentials);
然后将对服务的后续调用进行身份验证。请注意密码仅使用Base64进行编码,因此我建议您使用其他附加机制(如客户端证书)来提高安全性。
答案 4 :(得分:4)
有关基本身份验证的其他一些上下文,它包含一个包含键/值对的标头:
授权:基本Z2VybWFuOmdlcm1hbg ==
其中&#34; 授权 &#34;是标题键, 标题值包含一个字符串(&#34; 基本 &#34;字加 空格 )连接到&#34; Z2VybWFuOmdlcm1hbg == &#34;,这是<64>以双点连接的用户和密码
String name = "username";
String password = "secret";
String authString = name + ":" + password;
String authStringEnc = new BASE64Encoder().encode(authString.getBytes());
...
objectXXX.header("Authorization", "Basic " + authStringEnc);
答案 5 :(得分:2)
这对我有用:
BindingProvider bp = (BindingProvider) port;
Map<String, Object> map = bp.getRequestContext();
map.put(BindingProvider.USERNAME_PROPERTY, "aspbbo");
map.put(BindingProvider.PASSWORD_PROPERTY, "9FFFN6P");
答案 6 :(得分:1)
为了让您的生活更简单,您可能需要考虑使用JAX-WS框架,例如Apache CXF或Apache Axis2。
以下是描述如何为Apache CXF设置WS-Security的链接 - &gt; http://cxf.apache.org/docs/ws-security.html
修改强>
顺便说一句,Authorization
字段只使用简单的Base64编码。
根据此(http://www.motobit.com/util/base64-decoder-encoder.asp),解码值为german:german
。
答案 7 :(得分:0)
如果您使用JAX-WS,以下内容对我有用:
//Get Web service Port
WSTestService wsService = new WSTestService();
WSTest wsPort = wsService.getWSTestPort();
// Add username and password for Basic Authentication
Map<String, Object> reqContext = ((BindingProvider)
wsPort).getRequestContext();
reqContext.put(BindingProvider.USERNAME_PROPERTY, "username");
reqContext.put(BindingProvider.PASSWORD_PROPERTY, "password");
答案 8 :(得分:0)
最简单的方法是在请求下包含用户名和密码。请参阅下面的示例。
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:typ="http://xml.demo.com/types" xmlns:ser="http://xml.demo.com/location/services"
xmlns:typ1="http://xml.demo.com/location/types">
<soapenv:Header>
<typ:requestHeader>
<typ:timestamp>?</typ:timestamp>
<typ:sourceSystemId>TEST</typ:sourceSystemId>
<!--Optional: -->
<typ:sourceSystemUserId>1</typ:sourceSystemUserId>
<typ:sourceServerId>1</typ:sourceServerId>
<typ:trackingId>HYD-12345</typ:trackingId>
</typ:requestHeader>
<wsse:Security soapenv:mustUnderstand="1"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-emmprepaid"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>your-username</wsse:Username>
<wsse:Password
Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">your-password</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<ser:getLocation>
<!--Optional: -->
<ser:GetLocation>
<typ1:locationID>HYD-GoldenTulipsEstates</typ1:locationID>
</ser:GetLocation>
</ser:getLocation>
</soapenv:Body>
</soapenv:Envelope>