Pasé mucho tiempo en esto, pero finalmente encontré un ejemplo que actu aliado funciona. Está basado en Glassfish y Netbeans, pero supongo que podrías hacerlo funcionar en otros entornos (por ejemplo, Eclipse y Tomcat) si jugaste con él.
http://java.sun.com/webservices/reference/tutorials/wsit/doc/WSIT_Security9.html#wp162511
El problema que he encontrado es sin embargo cuando se quiere usar sus propios certificados, no los que vienen pre-instalado con glassfish.
Nota: No soy un experto en seguridad. ¡No implemente esto en un entorno de producción!
para hacer esto que estoy usando NetBeans 6.9, JDK 1.6, GlassFish 3.0.1 y v1.0 OpenSSL (estoy usando los binarios de Win32 no oficiales)
# Create the CA
mkdir ca server client
cd ca
openssl req -new -x509 -days 3650 -extensions v3_ca -keyout ca.key -out ca.pem
echo 02 > serial.txt
cd ..
# Creating the Server Keystore
openssl req -days 3650 -newkey rsa:1024 -keyout server/server.key -out server/server.req
openssl x509 -extensions usr_cert -extfile C:\testbed\OpenSSL-Win32\bin\openssl.cfg -CA ca/ca.pem -CAkey ca/ca.key -CAserial ca/serial.txt -req -in server/server.req -out server/server.crt
openssl pkcs12 -export -inkey server/server.key -in server/server.crt -out server/server.p12 -name server
keytool -importkeystore -destkeystore server/server.jks -deststoretype jks -srckeystore server/server.p12 -srcstoretype pkcs12
keytool -exportcert -alias server -keystore server/server.jks -file server/server.cer
# Create the Client Keystore
openssl req -days 3650 -newkey rsa:1024 -keyout client/client1.key -out client/client1.req
openssl x509 -extensions usr_cert -extfile C:\testbed\OpenSSL-Win32\bin\openssl.cfg -CA ca/ca.pem -CAkey ca/ca.key -CAserial ca/serial.txt -req -in client/client1.req -out client/client1.crt
openssl pkcs12 -export -inkey client/client1.key -in client/client1.crt -out client/client1.p12 -name client1
keytool -importkeystore -destkeystore client/client1.jks -deststoretype jks -srckeystore client/client1.p12 -srcstoretype pkcs12
keytool -exportcert -alias client1 -keystore client/client1.jks -file client/client1.cer
# Import public keys and certificates into each others keystores
keytool -import -noprompt -trustcacerts -alias client1 -file client/client1.cer -keystore server/server.jks
keytool -import -noprompt -trustcacerts -alias server -file server/server.cer -keystore client/client1.jks
keytool -import -noprompt -trustcacerts -alias my_ca -file ca/ca.pem -keystore server/server.jks
keytool -import -noprompt -trustcacerts -alias my_ca -file ca/ca.pem -keystore client/client1.jks
keytool -import -noprompt -trustcacerts -alias my_ca -file ca/ca.pem -keystore "C:\Program Files\glassfish-3.0.1\glassfish\domains\domain1\config\cacerts.jks"
keytool -import -noprompt -trustcacerts -alias my_ca -file ca/ca.pem -keystore "C:\Program Files\Java\jdk1.6\jre\lib\security\cacerts"
move "C:\Program Files\glassfish-3.0.1\glassfish\domains\domain1\config\keystore.jks" "C:\Program Files\glassfish-3.0.1\glassfish\domains\domain1\config\keystore.jks.backup"
copy server\server.jks "C:\Program Files\glassfish-3.0.1\glassfish\domains\domain1\config\keystore.jks"
En la consola de administración de GlassFish, habilite Seguridad en su oyente http, marque las casillas SSL3, TLS y Autenticación de cliente, configure Nickname del certificado en el servidor, Key Store en config \ keystore.jks, Trust Store en config \ keystore.jks, Trust Algorithm en PKIX y deje la Longitud máxima del certificado en 5.
En NetBeans, cree un nuevo proyecto de aplicación web. Dentro de eso, crea un nuevo servicio web.
Mi código de servicio Web se veía así:
@WebService()
public class ListProducts {
@Resource WebServiceContext context;
@WebMethod(operationName = "listProducts")
public String listProducts() {
return context.getUserPrincipal().toString();
}
}
Haga clic derecho sobre el servicio web y seleccionar Servicio Web Editar atributos. Marque la casilla Servicio seguro y seleccione Seguridad de certificados mutuos como el Mecanismo de seguridad. Haga clic en el botón Configurar ... y marque la casilla Cifrar firma. Ahora desmarque la casilla Usar valores predeterminados de desarrollo y luego haga clic en el botón Almacén de claves. Establezca la ubicación de su servidor de claves server.jks y seleccione el alias server
.Haz lo mismo para la configuración de Truststore (aunque no tienes que seleccionar un alias aquí).
Importe el certificado del cliente client1.p12 a su navegador. Implemente su servicio web a Glassfish. Abra su servicio web en un navegador y busque el WSDL implementado a través de HTTPS. Descargue el WSDL y cualquier otro esquema. Cambie el nombre de cualquier esquema referenciado a copias locales para que cuando use WSDL2Java NetBeans no use ningún recurso remoto. (Este párrafo se debe a que ha restringido su WSDL a clientes con un certificado aprobado, pero NetBeans no puede recuperarlo de forma remota porque no tiene acceso al certificado en cuestión).
Cree un nuevo proyecto de Java. Crea un nuevo cliente de servicio web. Cuando se le solicite, señale NetBeans en su archivo WSDL guardado. Importe los archivos de la biblioteca METRO2.0 (C:\Program Files\Netbeans 6.9\enterprise\modules\ext\metr\webservices-*.jar
). Mi código se veía así:
public static void main(String[] args) {
System.getProperties().put("javax.net.ssl.keyStore", "C:\\NetBeansProjects\\security-04\\ssl\\client\\client1.jks");
System.getProperties().put("javax.net.ssl.keyStorePassword", "changeit");
System.getProperties().put("javax.net.ssl.trustStore", "C:\\NetBeansProjects\\security-04\\ssl\\client\\client1.jks");
System.getProperties().put("javax.net.ssl.trustStorePassword", "changeit");
System.out.println(new ListProductsService().getListProductsPort().listProducts());
}
Copia webservices-api.jar en su Java \ jdk1.6 \ jre \ lib \ directorio respaldado. Haga clic con el botón derecho en la referencia del servicio web y seleccione Editar atributos del servicio web. Establezca la ubicación del almacén de claves en client1.jks y configure el alias en client1
. Establezca la ubicación del almacén de confianza en client1.jks y establezca el alias en server
.
Esperamos que usted puede ahora ejecutar su cliente y debería ver una salida de este modo: [email protected], CN=Bob Smith, OU=Something, O=SomethingElse, L=AnyTown, ST=AnyState, C=US
A pesar de que he explicado el concepto de autenticación mutua bastante bien, los enlaces no son muy útiles en absoluto. ¡La seguridad del servicio web Java ha cambiado bastante desde 2006! :) – Catchwa