web-dev-qa-db-fra.com

Quelle est la bonne façon d'envoyer un certificat client avec chaque demande faite par le resttemplate au printemps?

je souhaite utiliser un service REST avec mon application Spring. Pour accéder à ce service, j'ai un certificat client (auto-signé et au format .jks) d'autorisation .. Quel est le moyen approprié de s'authentifier auprès du service de repos?

C'est ma demande:

public List<Info> getInfo() throws RestClientException, URISyntaxException {

    HttpEntity<?> httpEntity = new HttpEntity<>(null, new HttpHeaders());

    ResponseEntity<Info[]> resp = restOperations.exchange(
            new URI(BASE_URL + "/Info"), HttpMethod.GET, 
            httpEntity, Info[].class);
    return Arrays.asList(resp.getBody());
}
6
Nas3nmann

Voici un exemple d'utilisation de RestTemplate et Apache HttpClient

Vous devez définir votre propre RestTemplate avec le contexte SSL configuré:

@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) throws Exception {
    char[] password = "password".toCharArray();

    SSLContext sslContext = SSLContextBuilder.create()
            .loadKeyMaterial(keyStore("classpath:cert.jks", password), password)
            .loadTrustMaterial(null, new TrustSelfSignedStrategy()).build();

    HttpClient client = HttpClients.custom().setSSLContext(sslContext).build();
    return builder
            .requestFactory(new HttpComponentsClientHttpRequestFactory(client))
            .build();
}

 private KeyStore keyStore(String file, char[] password) throws Exception {
    KeyStore keyStore = KeyStore.getInstance("PKCS12");
    File key = ResourceUtils.getFile(file);
    try (InputStream in = new FileInputStream(key)) {
        keyStore.load(in, password);
    }
    return keyStore;
}

Désormais, tous les appels distants effectués par ce modèle seront signés avec cert.jks.Remarque: vous devez insérer cert.jks dans votre chemin

@Autowired
private RestTemplate restTemplate;

public List<Info> getInfo() throws RestClientException, URISyntaxException {
    HttpEntity<?> httpEntity = new HttpEntity<>(null, new HttpHeaders());

    ResponseEntity<Info[]> resp = restTemplate.exchange(
            new URI(BASE_URL + "/Info"), HttpMethod.GET, 
            httpEntity, Info[].class);
    return Arrays.asList(resp.getBody());
}
14
Ruslan Poshuk

Ou vous pouvez simplement importer le certificat dans vos comptes JDK et tous les clients HTTP utilisant le jdk (modèle de repos dans votre cas) utiliseront le certificat pour effectuer l'appel REST.

keytool -import -keystore $Java_HOME/jre/lib/security/cacerts -file foo.cer -alias alias

P.S: N'oubliez pas de redémarrer votre serveur après une importation réussie. Mot de passe par défaut pour le magasin de clés - changeit

1
Abhijeet