Utilisation de HTTPS avec REST en Java
j'ai un serveur REST fait en Grizzly qui utilise HTTPS et fonctionne merveilleusement avec Firefox. Voici le code:
//Build a new Servlet Adapter.
ServletAdapter adapter=new ServletAdapter();
adapter.addInitParameter("com.sun.jersey.config.property.packages", "My.services");
adapter.addInitParameter(ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS, SecurityFilter.class.getName());
adapter.setContextPath("/");
adapter.setServletInstance(new ServletContainer());
//Configure SSL (See instructions at the top of this file on how these files are generated.)
SSLConfig ssl=new SSLConfig();
String keystoreFile=Main.class.getResource("resources/keystore_server.jks").toURI().getPath();
System.out.printf("Using keystore at: %s.",keystoreFile);
ssl.setKeyStoreFile(keystoreFile);
ssl.setKeyStorePass("asdfgh");
//Build the web server.
GrizzlyWebServer webServer=new GrizzlyWebServer(getPort(9999),".",true);
//Add the servlet.
webServer.addGrizzlyAdapter(adapter, new String[]{"/"});
//Set SSL
webServer.setSSLConfig(ssl);
//Start it up.
System.out.println(String.format("Jersey app started with WADL available at "
+ "%sapplication.wadln",
"https://localhost:9999/"));
webServer.start();
Maintenant, j'essaie de l'atteindre en Java:
SSLContext ctx=null;
try {
ctx = SSLContext.getInstance("SSL");
} catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
}
ClientConfig config=new DefaultClientConfig();
config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties(null,ctx));
WebResource service=Client.create(new DefaultClientConfig()).resource("https://localhost:9999/");
//Attempt to view the user's page.
try{
service
.path("user/"+username)
.get(String.class);
}
et obtenir:
com.sun.jersey.api.client.ClientHandlerException: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:128)
at com.sun.jersey.api.client.Client.handle(Client.java:453)
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:557)
at com.sun.jersey.api.client.WebResource.get(WebResource.java:179)
D'après les exemples que j'ai trouvés sur le web, il semble que j'aurais besoin de mettre en place une librairie puis de mettre en place une sorte de gestionnaire de confiance. Cela semble comme beaucoup de code et de travail d'installation pour mon petit projet simple. Être il y a une façon plus facile de le dire..Je fais confiance à ce cert et pointe vers A.fichier cert?
4 réponses
Quand vous dites "est-il un moyen plus facile... faites confiance à ce cert", c'est exactement ce que vous faites en ajoutant le cert à votre boutique Java trust. Et c'est très, très facile à faire, et il n'y a rien que vous devez faire dans votre application client pour faire reconnaître ou utiliser ce magasin de confiance.
sur votre machine client, trouvez où se trouve votre fichier cacerts (C'est votre Java trust store par défaut, et est, par défaut, situé à
ensuite, tapez ce qui suit:
keytool -import -alias <Name for the cert> -file <the .cer file> -keystore <path to cacerts>
qui importera le cert dans votre boutique en fiducie, et après cela, votre application client sera en mesure de se connecter à votre serveur HTTPS Grizzly sans problème.
si vous ne voulez pas importer le cert dans votre magasin de confiance par défaut -- c.-à-d., vous voulez juste qu'il soit disponible pour cette application client unique, mais pas pour quoi que ce soit d'autre que vous exécutez sur votre JVM sur cette machine -- alors vous pouvez créer un nouveau trust store juste pour votre application. Au lieu de passer keytool le chemin vers le fichier cacerts existant par défaut, passez keytool le chemin vers votre nouveau fichier de confiance:
keytool -import -alias <Name for the cert> -file <the .cer file> -keystore <path to new trust store>
il vous sera demandé de définir et de vérifier un nouveau mot de passe pour le fichier de la boutique en fiducie. Ensuite, lorsque vous démarrez votre application cliente, le démarrer avec les paramètres suivants:
java -Djavax.net.ssl.trustStore=<path to new trust store> -Djavax.net.ssl.trustStorePassword=<trust store password>
fastoche, vraiment.
Voici la route douloureuse:
SSLContext ctx = null;
try {
KeyStore trustStore;
trustStore = KeyStore.getInstance("JKS");
trustStore.load(new FileInputStream("C:\truststore_client"),
"asdfgh".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory
.getInstance("SunX509");
tmf.init(trustStore);
ctx = SSLContext.getInstance("SSL");
ctx.init(null, tmf.getTrustManagers(), null);
} catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
ClientConfig config = new DefaultClientConfig();
config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES,
new HTTPSProperties(null, ctx));
WebResource service = Client.create(config).resource(
"https://localhost:9999/");
service.addFilter(new HTTPBasicAuthFilter(username, password));
// Attempt to view the user's page.
try {
service.path("user/" + username).get(String.class);
} catch (Exception e) {
e.printStackTrace();
}
Gotta love ces six différents pris des exceptions :). Il y a certainement quelques remaniements pour simplifier un peu le code. Mais, j'aime les options delfuego-D sur la VM. J'aimerais qu'il y ait un javax.net.ssl.une propriété fixe que je pourrais installer. Seulement deux lignes de code et fait. Quelqu'un sait où ce serait?
C'est peut-être trop demander, mais, idéalement, l'utilitaire keytool ne seraient pas utilisés. Au lieu de cela, le trustedStore serait créé dynamiquement par le code et le cert est ajouté à l'exécution.
Il doit y avoir une meilleure réponse.
une chose à garder à l'esprit est que cette erreur n'est pas seulement due à des certs auto signés. Les nouveaux certs Entrust CA échouent avec la même erreur, et la bonne chose à faire est de mettre à jour le serveur avec les certs root appropriés, et non de désactiver cette importante fonctionnalité de sécurité.
Check this out: http://code.google.com/p/resting / . Je pourrais utiliser le repos pour consommer Services de repos HTTPS.