example - web service client soap header java
Autenticación básica del cliente de Java Web Service (7)
Algún contexto adicional sobre autenticación básica, consiste en un encabezado que contiene el par clave / valor:
Autorización: Basic Z2VybWFuOmdlcm1hbg ==
donde " Autorización " es la clave de encabezados, y el valor de encabezados tiene una cadena (palabra " Básica " más espacio en blanco ) concatenada a " Z2VybWFuOmdlcm1hbg == ", que son el usuario y la contraseña en la base 64 conjunta por doble punto
String name = "username";
String password = "secret";
String authString = name + ":" + password;
String authStringEnc = new BASE64Encoder().encode(authString.getBytes());
...
objectXXX.header("Authorization", "Basic " + authStringEnc);
Creé un servicio web JAX-WS encima de Glassfish que requiere autenticación HTTP básica.
Ahora quiero crear un cliente de aplicación java independiente para ese servicio web, pero no tengo ni idea de cómo pasar el nombre de usuario y la contraseña.
Funciona con el explorador de servicios web de Eclipse, y al examinar el cable encontré esto:
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>
¿Cómo paso el nombre de usuario y la contraseña en este encabezado de "Autorización" usando el código de Java? ¿Es hash o algo así? ¿Cuál es el algoritmo?
Sin la seguridad involucrada, tengo un cliente java independiente que funciona:
SnaProvisioning myPort = new SnaProvisioning_Service().getSnaProvisioningV10Port();
myPort.listServiceScripts();
El modo JAX-WS para autenticación básica es
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();
Para simplificar su vida, puede considerar usar el marco JAX-WS como Apache CXF o Apache Axis2.
Aquí está el enlace que describe cómo configurar WS-Security para Apache CXF -> http://cxf.apache.org/docs/ws-security.html
EDITAR Por cierto, el campo Authorization
solo usa codificación Base64 simple. De acuerdo con esto ( http://www.motobit.com/util/base64-decoder-encoder.asp ), el valor decodificado es german:german
.
Resultó que hay una manera simple y estándar de lograr lo que quería:
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);
No hay clases de "sol" personalizadas ni dependencias externas, y no codifica nada manualmente.
Soy consciente de que la seguridad de BASIC no es, bueno, segura, pero también estamos usando HTTPS.
Si está utilizando una implementación JAX-WS para su cliente, como Metro Web Services, el siguiente código muestra cómo pasar el nombre de usuario y la contraseña en los encabezados 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);
Luego, las llamadas posteriores al servicio serán autenticadas. Tenga en cuenta que la contraseña solo se codifica con Base64, por lo que le recomendamos que utilice otro mecanismo adicional, como certificados de clientes, para aumentar la seguridad.
así me funciono:
BindingProvider bp = (BindingProvider) port; Map<String, Object> map = bp.getRequestContext(); map.put(BindingProvider.USERNAME_PROPERTY, "aspbbo"); map.put(BindingProvider.PASSWORD_PROPERTY, "9FFFN6P");
para el cliente Axis2
esto puede ser útil
...
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");
...