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

时间:2011-08-15 22:05:15

标签: java web-services java-ee jax-ws

我在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();

9 个答案:

答案 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>