Authentification de base du client Java Web Service
J'ai créé un Service web JAX-WS au-dessus de Glassfish qui nécessite une authentification HTTP de base.
Maintenant, je veux créer un client d'application java autonome pour ce service Web, mais je n'ai pas la moindre idée de la façon de passer le nom d'utilisateur et le mot de passe.
Cela fonctionne avec L'Explorateur de service 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 passer le nom d'utilisateur et le mot de passe dans cet en-tête "autorisation" en utilisant du code java? Est-ce haché ou quelque chose comme qui? Qu'est-ce que l'algorithme?
Sans sécurité impliquée, j'ai un client java autonome fonctionnant:
SnaProvisioning myPort = new SnaProvisioning_Service().getSnaProvisioningV10Port();
myPort.listServiceScripts();
7 réponses
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();
Il S'est avéré qu'il existe un moyen simple et standard de réaliser 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é de base n'est pas, eh bien, sécurisée, mais nous utilisons également HTTPS.
Pour le client Axis2
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");
...
Si vous utilisez une implémentation JAX-WS pour votre client, telle que Metro Web Services, le code suivant indique comment passer le nom d'utilisateur et le 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. Méfiez-vous que le mot de passe n'est encodé qu'en Base64, donc je vous encourage à utiliser d'autres mécanismes supplémentaires comme les certificats clients pour augmenter la sécurité.
Un contexte supplémentaire sur l'authentification de base, il consiste en un en-tête qui contient la paire clé / valeur:
Autorisation: Base Z2VybWFuOmdlcm1hbg==
Où "Autorisation" les en-têtes de clé, et la valeur headers a une chaîne ( "Base" MOT plus espace vide) concaténé à "Z2VybWFuOmdlcm1hbg==", Quels 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);
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 rendre votre vie plus simple , Vous pouvez envisager d'utiliser le framework JAX-WS tel Qu'Apache CXF ou Apache Axis2.
Voici le lien qui décrit comment configurer WS-Security pour Apache CXF - > http://cxf.apache.org/docs/ws-security.html
Modifier
En passant, le champ Authorization
utilise simplement un codage Base64 simple.
Selon cette ( http://www.motobit.com/util/base64-decoder-encoder.asp ), la valeur décodée est german:german
.