RestTemplate mit Digest-Authentifizierung

RestTemplate mit Digest-Authentifizierung

1. Überblick

Dieser Artikel zeigt, wie manconfigure the Spring RestTemplate to consume a service secured with Digest Authentication macht.

Ähnlich wie bei der Standardauthentifizierung kann der Client nach dem Festlegen der Digest-Authentifizierung in der Vorlage die erforderlichen Sicherheitsschritte ausführen und die für den Header vonAuthorizationerforderlichen Informationen abrufen:

Authorization: Digest
    username="user1",
    realm="Custom Realm Name",
    nonce="MTM3NTYwOTA5NjU3OTo5YmIyMjgwNTFlMjdhMTA1MWM3OTMyMWYyNDY2MGFlZA==",
    uri="/spring-security-rest-digest-auth/api/foos/1",
    ....

Mit diesen Daten kann der Server die Anforderung korrekt authentifizieren und die 200-OK-Antwort zurückgeben.

2. Richten SieRestTemplate ein

DieRestTemplate müssen alsa bean in the Spring context deklariert werden - dies ist entweder in XML oder in einfachem Java unter Verwendung der Annotation@Bean einfach genug:

import org.apache.http.HttpHost;
import org.example.client.HttpComponentsClientHttpRequestFactoryDigestAuth;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ClientConfig {

    @Bean
    public RestTemplate restTemplate() {
        HttpHost host = new HttpHost("localhost", 8080, "http");
        CloseableHttpClient client = HttpClientBuilder.create().
          setDefaultCredentialsProvider(provider()).useSystemProperties().build();
        HttpComponentsClientHttpRequestFactory requestFactory =
          new HttpComponentsClientHttpRequestFactoryDigestAuth(host, client);

        return new RestTemplate(requestFactory);;
    }

    private CredentialsProvider provider() {
        CredentialsProvider provider = new BasicCredentialsProvider();
        UsernamePasswordCredentials credentials =
          new UsernamePasswordCredentials("user1", "user1Pass";
        provider.setCredentials(AuthScope.ANY, credentials);
        return provider;
    }
}

Der größte Teil der Konfiguration des Digest-Zugriffsmechanismus erfolgt in der benutzerdefinierten Implementierung der Client-http-Anforderungsfactory, die in die Vorlage -HttpComponentsClientHttpRequestFactoryDigestAuth eingefügt wird.

Beachten Sie, dass wir die Vorlage jetzt mit den Anmeldeinformationen vorkonfigurieren, die Zugriff auf die gesicherte API haben.

3. Konfigurieren Sie die Digest-Authentifizierung

Wir werden die in Spring 3.1 eingeführte Unterstützung für den aktuellen HttpClient 4.x - nämlichHttpComponentsClientHttpRequestFactory - nutzen, indem wir ihn erweitern und konfigurieren.

Wir werden hauptsächlichHttpContextkonfigurieren und unsere benutzerdefinierte Logik für die Digest-Authentifizierung anschließen:

import java.net.URI;
import org.apache.http.HttpHost;
import org.apache.http.client.AuthCache;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.auth.DigestScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;

public class HttpComponentsClientHttpRequestFactoryDigestAuth
  extends HttpComponentsClientHttpRequestFactory {

    HttpHost host;

    public HttpComponentsClientHttpRequestFactoryDigestAuth(HttpHost host) {
        super(httpClient);
        this.host = host;
    }

    @Override
    protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) {
        return createHttpContext();
    }

    private HttpContext createHttpContext() {
        // Create AuthCache instance
        AuthCache authCache = new BasicAuthCache();
        // Generate DIGEST scheme object, initialize it and add it to the local auth cache
        DigestScheme digestAuth = new DigestScheme();
        // If we already know the realm name
        digestAuth.overrideParamter("realm", "Custom Realm Name");
        authCache.put(host, digestAuth);

        // Add AuthCache to the execution context
        BasicHttpContext localcontext = new BasicHttpContext();
        localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);
        return localcontext;
    }
}

Jetzt können dieRestTemplate einfach injiziert und in einem Test verwendet werden:

@Test
public void whenSecuredRestApiIsConsumed_then200OK() {
    String uri = "http://localhost:8080/spring-security-rest-digest-auth/api/foos/1";
    ResponseEntity entity = restTemplate.exchange(uri, HttpMethod.GET, null, Foo.class);
    System.out.println(entity.getStatusCode());
}

Um den vollständigen Konfigurationsprozess zu veranschaulichen, werden in diesem Test auch die Benutzeranmeldeinformationen eingerichtet -user1 unduser1Pass. Dieser Teil sollte natürlichonly once and outside the test itself sein.

4. Maven-Abhängigkeiten

Die erforderlichen Maven-Abhängigkeiten fürRestTemplate und die HttpClient-Bibliothek sind:


   org.springframework
   spring-webmvc
   4.1.1.RELEASE



   org.apache.httpcomponents
   httpclient
   4.3.5

5. Fazit

Dieses Tutorial zeigte, wie manconfigure the Rest Template so that it can consume an application secured with Digest authentication einrichtet. Die REST-API selbst muss der Mechanismus vonconfigured with the digest securityein.

Die Implementierung befindet sich inthe example GitHub project - dies ist ein Maven-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein.