J'ai créé un service Web JAX-WS sur Glassfish, qui requiert une authentification HTTP de base.
Maintenant, je veux créer un client d'application autonome Java pour ce service Web, mais je ne sais pas comment passer le nom d'utilisateur et le mot de passe.
Cela fonctionne avec l'explorateur de services Web d'Eclipse, et en examinant le fil, j'ai trouvé ceci:
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>
Comment puis-je passer le nom d'utilisateur et le mot de passe dans cet en-tête "Authorization" à l'aide du code Java? Est-il haché ou quelque chose du genre? Quel est l'algorithme?
Sans sécurité impliquée, j'ai un client autonome Java client:
SnaProvisioning myPort = new SnaProvisioning_Service().getSnaProvisioningV10Port();
myPort.listServiceScripts();
Il s'est avéré qu'il existe un moyen simple et standard d'atteindre ce que je voulais:
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);
Pas de classes "Sun" personnalisées ou de dépendances externes, et pas d'encodage manuel.
Je suis conscient que la sécurité BASIC n'est pas, eh bien, sécurisée, mais nous utilisons également le protocole HTTPS.
La méthode JAX-WS pour l’authentification de base est
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();
pour Axis2
client cela peut être utile
...
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");
...
Une partie du contexte supplémentaire à propos de l’authentification de base, elle consiste en un en-tête qui contient la paire clé/valeur:
Autorisation: Base Z2VybWFuOmdlcm1hbg ==
où " Authorization " est la clé de l'en-tête et la valeur de l'en-tête comporte une chaîne (" Base "Word plus espace vide ) concaténé à " Z2VybWFuOmdlcm1hbg == ", qui sont l'utilisateur et le mot de passe dans la base 64 joint par double point
String name = "username";
String password = "secret";
String authString = name + ":" + password;
String authStringEnc = new BASE64Encoder().encode(authString.getBytes());
...
objectXXX.header("Authorization", "Basic " + authStringEnc);
Si vous utilisez une implémentation JAX-WS pour votre client, telle que Metro Web Services, le code suivant montre comment passer un nom d'utilisateur et un mot de passe dans les en-têtes 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);
Ensuite, les appels suivants au service seront authentifiés. Attention, le mot de passe est uniquement codé avec Base64. Je vous encourage donc à utiliser un autre mécanisme supplémentaire, tel que les certificats clients, pour renforcer la sécurité.
Cela a fonctionné pour moi:
BindingProvider bp = (BindingProvider) port;
Map<String, Object> map = bp.getRequestContext();
map.put(BindingProvider.USERNAME_PROPERTY, "aspbbo");
map.put(BindingProvider.PASSWORD_PROPERTY, "9FFFN6P");
Pour vous simplifier la vie plus simple, vous pouvez envisager d’utiliser un framework JAX-WS tel que Apache CXF ou Apache Axis2.
Voici le lien qui explique comment configurer WS-Security pour Apache CXF -> http://cxf.Apache.org/docs/ws-security.html
[~ # ~] éditer [~ # ~] En passant, le champ Authorization
utilise simplement un encodage Base64 simple. Selon cela ( http://www.motobit.com/util/base64-decoder-encoder.asp ), la valeur décodée est german:german
.
Si vous utilisez JAX-WS, ce qui suit fonctionne pour moi:
//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");