Solución:
Lo que busca se llama Autenticación mutua.
Es responsabilidad del servidor hacer / solicitar al cliente que envíe su certificado. Cada servidor hace esto de manera diferente y tendrá que buscar cómo configurar su servidor en particular.
Para Spring Security, recomendaría buscar en la autenticación X.509. Este tipo de autenticación es bastante fácil de usar y ampliar según sea necesario.
EDITAR
Entonces, aquí hay un par de referencias que muestran ejemplos de lo que está preguntando:
http://whiteycode.blogspot.com/2012/04/part-3-x509-authentication-with-spring.html
Advertencia de PDF
http://www.promixis.com/pdfs/SpringSecurityAndX509ClientCertificates.pdf
Ya no se puede acceder al archivo pdf anterior …
Este ejemplo es realmente bueno para explicar cómo configurar sus certificados y crear su propia CA (Autoridad de certificación) personal. Advertencia, la forma en que muestran al hacer el certificado de cliente es solo UNA MANERA, no la manera. Su cliente (navegador web IE o cliente httpclient java) debe determinar de qué manera crear su certificado de cliente. A Java le gusta usar su almacén de claves de Java, por supuesto, y a los navegadores les suele gustar el estilo de certificados p12.
Advertencia / consejo final … No conozco su nivel de conocimiento con los certificados, pero … La autenticación mutua se trata de quién confía en quién. Es responsabilidad del servidor decir, necesito que se autentique con un certificado y aquí hay una lista de proveedores de certificados en los que confío. Entonces, es responsabilidad del cliente responder con un certificado firmado por uno de esos proveedores de certificados de confianza del servidor. Es responsabilidad de la aplicación decir, ¿confío en esta persona en función de su nombre dentro del certificado? Si las cosas empiezan a salir mal, piensa en quién y quién no confía en quién.
Una gran herramienta es usar -Djavax.net.debug = ssl en su aplicación. Mostrará el protocolo de enlace SSL completo y lo que se solicita y cuáles son las respuestas específicas. Esa opción es un poco detallada, pero es bueno tenerla cuando sea necesario.
EDITAR X 2
A continuación, se explica cómo habilitar la autenticación mutua en Tomcat 7.
En su archivo de configuración server.xml, debería ver cerca de lo siguiente para un conector SSL:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="want" sslProtocol="TLS"
keystoreFile="C:JavaCertslocalhost.jks"
keystorePass="changeit"
URIEncoding="UTF-8" />
El valor importante a tener en cuenta es el valor de clientAuth.
Configurar clientAuth en ‘querer’ le dice al cliente que envíe un certificado ssl de cliente firmado de una lista de certificados en los que el servidor confía si tiene uno. Si no es así, continúe y haga su solicitud con normalidad.
Establecer clientAuth en ‘true’ le dice al cliente que TIENEN que enviar un certificado ssl de cliente firmado de una lista de certificados en los que el servidor confía. Si no tiene un certificado firmado por una lista de certificados en los que el servidor confía, el cliente NO puede realizar la solicitud.
La lista de certificados en los que confía el servidor proviene del almacén de confianza predeterminado de Java o se puede configurar mediante el -Djavax.net.ssl.trustStore="C:JavaCertsjssecacerts1"
Opción VM.
Generalmente, cuando tiene un certificado de CA específico en el que confía que no está en el almacén de confianza predeterminado de Java, el almacén de confianza predeterminado se copia, el nuevo certificado de CA se importa al almacén de confianza copiado y luego se usa con la opción de VM anterior.
ADVERTENCIA
Es muy importante NO cambiar el almacén de confianza de Java predeterminado en su lugar. Si lo hace, todas las aplicaciones Java de forma predeterminada en esa máquina utilizarán el nuevo almacén de confianza actualizado. No siempre es lo que la gente quiere y puede causar riesgos de seguridad.
Creé un proyecto de ejemplo 100% comprensible con todo necesario para configurar una aplicación Spring Boot con un punto final REST que está protegido por un certificado de cliente, y un Testcase con RestTemplate que está configurado para usar el certificado de cliente para comunicarse con el servidor seguro: https://github.com/jonashackt/spring -boot-rest-clientcertificate
También contiene todos pasos necesarios para generar el .key
, .crt
y .jks
archivos. Simplemente ajuste los pasos en consecuencia, si no desea utilizar un certificado autofirmado.
RestTemplate se configura así:
package de.jonashackt.restexamples;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.util.ResourceUtils;
import org.springframework.web.client.RestTemplate;
import javax.net.ssl.SSLContext;
@Configuration
public class RestClientCertTestConfiguration {
private String allPassword = "allpassword";
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) throws Exception {
SSLContext sslContext = SSLContextBuilder
.create()
.loadKeyMaterial(ResourceUtils.getFile("classpath:keystore.jks"), allPassword.toCharArray(), allPassword.toCharArray())
.loadTrustMaterial(ResourceUtils.getFile("classpath:truststore.jks"), allPassword.toCharArray())
.build();
HttpClient client = HttpClients.custom()
.setSSLContext(sslContext)
.build();
return builder
.requestFactory(new HttpComponentsClientHttpRequestFactory(client))
.build();
}
}
Entonces puedes usarlo como estás acostumbrado con el @Autowired
anotación dentro de su Test.class.