1. 概要

この記事では、ダイジェスト認証で保護されたサービスを利用するようにSpringRestTemplateを構成する方法を示します。

基本認証と同様に、ダイジェスト認証がテンプレートに設定されると、クライアントは必要なセキュリティ手順を実行し、Authorizationヘッダーに必要な情報を取得できるようになります。

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

このデータを使用して、サーバーは要求を正しく認証し、200OK応答を返すことができます。

2. RestTemplateを設定します

RestTemplate は、Springコンテキスト a Beanとして宣言する必要があります。これは、 @Bean アノテーションを使用して、XMLまたはプレーンJavaで十分に単純です。

import org.apache.http.HttpHost;
import com.baeldung.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;
    }
}

ダイジェストアクセスメカニズムの構成のほとんどは、テンプレートに挿入されたクライアントhttpリクエストファクトリのカスタム実装で行われます– HttpComponentsClientHttpRequestFactoryDigestAuth

保護されたAPIにアクセスできる資格情報を使用してテンプレートを事前構成していることに注意してください。

3. ダイジェスト認証を構成する

Spring 3.1で導入された現在のHttpClient4.xのサポート(つまり、 HttpComponentsClientHttpRequestFactory )を拡張して構成することにより、これを活用します。

主にHttpContextを構成し、ダイジェスト認証用のカスタムロジックを接続します。

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, HttpClient httpClient) {
        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;
    }
}

これで、 RestTemplate を簡単に挿入して、テストで使用できます。

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

完全な構成プロセスを説明するために、このテストではユーザー資格情報– user1およびuser1Passも設定します。 もちろん、この部分は、テスト自体の外で1回だけ実行する必要があります。

4. Mavenの依存関係

RestTemplateおよびHttpClientライブラリに必要なMavenの依存関係は次のとおりです。

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>5.2.8.RELEASE</version>
</dependency>

<dependency>
   <groupId>org.apache.httpcomponents</groupId>
   <artifactId>httpclient</artifactId>
   <version>4.3.5</version>
</dependency>

5. 結論

このチュートリアルでは、ダイジェスト認証で保護されたアプリケーションを使用できるように、RESTテンプレートをセットアップおよび構成する方法を示しました。 REST API自体は、ダイジェストセキュリティメカニズムを使用して構成する必要があります。

実装はサンプルのGitHubプロジェクトにあります。これはMavenベースのプロジェクトであるため、そのままインポートして実行するのは簡単です。