Java Web Service客户端基本身份验证

Ger*_*man 45 java web-services jax-ws java-ee

我在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>
Run Code Online (Sandbox Code Playgroud)

如何使用java代码在此"Authorization"标头中传递用户名和密码?它是哈希还是类似的东西?算法是什么?

如果没有安全性,我有一个独立的java客户端:

SnaProvisioning myPort = new SnaProvisioning_Service().getSnaProvisioningV10Port();
myPort.listServiceScripts();
Run Code Online (Sandbox Code Playgroud)

Jon*_*ero 67

用于基本身份验证的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();
Run Code Online (Sandbox Code Playgroud)


Ger*_*man 46

事实证明,有一种简单,标准的方式来实现我想要的:

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);
Run Code Online (Sandbox Code Playgroud)

没有自定义的"sun"类或外部依赖项,也没有手动编码任何东西.

我知道BASIC安全性不是很安全,但我们也使用HTTPS.

  • 请注意,`Authenticator #setDefault`不是线程安全的,如果您的服务使用者遇到多个端点,这不是一个好的解决方案. (17认同)
  • 如果您希望以后以编程方式更改凭据,您可能会遇到[this](http://stackoverflow.com/questions/480895/reset-the-authenticator-credentials)与[this]相关的问题(http://错误. java.com/bugdatabase/view_bug.do?bug_id=6626700)错误/缺陷.如果只有服务端口受基本身份验证保护,最简单的解决方案是(再一次)Jonathan的回答.如果WSDL本身受到保护,那么只有另一个线程中描述的丑陋的变通方法. (3认同)

小智 10

对于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");
...
Run Code Online (Sandbox Code Playgroud)


Jos*_*ara 6

关于基本身份验证的一些附加上下文,它包含一个包含键/值对的标头:

授权:基本Z2VybWFuOmdlcm1hbg ==

其中“ Authorization ”是标题密钥,并且标题值具有一个字符串(“ Basic ”单词加空格)连接到“ Z2VybWFuOmdlcm1hbg == ”,这是用双点连接的base 64用户和密码

String name = "username";
String password = "secret";
String authString = name + ":" + password;
String authStringEnc = new BASE64Encoder().encode(authString.getBytes());
...
objectXXX.header("Authorization", "Basic " + authStringEnc);
Run Code Online (Sandbox Code Playgroud)


Gon*_*gui 5

如果您正在为客户端使用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);
Run Code Online (Sandbox Code Playgroud)

然后,将对该服务的后续调用进行身份验证。请注意,密码仅使用Base64进行编码,因此建议您使用其他附加机制(例如客户端证书)来提高安全性。


小智 5

这对我有用:

 BindingProvider bp = (BindingProvider) port;
 Map<String, Object> map = bp.getRequestContext();
 map.put(BindingProvider.USERNAME_PROPERTY, "aspbbo");
 map.put(BindingProvider.PASSWORD_PROPERTY, "9FFFN6P");
Run Code Online (Sandbox Code Playgroud)

  • 请使用英文 (4认同)