知識庫 / HTTP Client-Side RSS 訂閱

RestTemplate 使用 Digest 身份驗證

HTTP Client-Side,Security,Spring Web
HongKong
6
03:08 PM · Dec 06 ,2025

1. 概述

本文將演示如何配置 Spring RestTemplate 以消費使用 Digest 身份驗證保護的服務。

類似於 Basic 身份驗證,一旦在模板中設置 Digest 身份驗證,客户端將能夠完成必要的安全步驟並獲取用於 Authorization 標頭所需的信息。

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

使用這些數據,服務器可以正確地驗證請求並返回 200 OK 響應。

2. 設置 RestTemplate

需要將 RestTemplate 聲明為 Spring 上下文中一個 Bean – 這在 XML 或純 Java 中都相對簡單,只需使用 @Bean 註解:

import org.apache.hc.client5.http.auth.AuthScope;
import org.apache.hc.client5.http.auth.CredentialsProvider;
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.core5.http.HttpHost;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import com.baeldung.client.HttpComponentsClientHttpRequestFactoryDigestAuth;

@Configuration
public class ClientConfig {
    private static final String DEFAULT_USER = "user1";
    private static final String DEFAULT_PASS = "user1Pass";

    public ClientConfig() {
        super();
    }

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

        return new RestTemplate(requestFactory);
    }

    private CredentialsProvider provider() {
        BasicCredentialsProvider provider = new BasicCredentialsProvider();
        UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(DEFAULT_USER, DEFAULT_PASS.toCharArray());
        //defining null and -1 it applies to any host and any port
        final AuthScope authScope = new AuthScope(null, -1);
        provider.setCredentials(authScope, credentials);
        return provider;
    }

}

大部分 digest 訪問機制的配置都在注入到模板中的自定義 http 請求工廠 HttpComponentsClientHttpRequestFactoryDigestAuth 中進行。

請注意,我們現在已經使用具有訪問受保護 API 憑據的憑據預先配置了模板。

3. 配置摘要身份驗證

我們將利用 Spring 3.1 引入的 HttpClient 4.x 的支持——即 HttpComponentsClientHttpRequestFactory —— 通過擴展和配置它。

我們將主要配置 HttpContext 並連接我們的自定義 Digest 身份驗證邏輯:

import org.apache.hc.client5.http.auth.AuthCache;
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
import org.apache.hc.client5.http.classic.HttpClient;
import org.apache.hc.client5.http.impl.auth.BasicAuthCache;
import org.apache.hc.client5.http.impl.auth.DigestScheme;
import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.protocol.BasicHttpContext;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;

import java.net.URI;

public class HttpComponentsClientHttpRequestFactoryDigestAuth extends HttpComponentsClientHttpRequestFactory {
    HttpHost host;

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

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

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

        // digestAuth.overrideParamter("nonce", "MTM3NTU2OTU4MDAwNzoyYWI5YTQ5MTlhNzc5N2UxMGM5M2Y5M2ViOTc4ZmVhNg==");
        authCache.put(host, digestAuth);

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

}

現在,RestTemplate 可以簡單地注入並用於測試:

@Test
public void whenSecuredRestApiIsConsumed_then200OK() throws IOException {
    CloseableHttpClient httpClient = HttpClientBuilder.create().build();
    HttpGet getMethod = new HttpGet("http://localhost:8082/spring-security-rest-basic-auth/api/bars/1");
    HttpResponse response = httpClient.execute(getMethod);
    System.out.println("HTTP Status of response: " + response.getCode());
}

為了説明完整的配置過程,本次測試也設置了用户憑據——user1user1Pass。 這部分當然應該只在一次且在測試之外完成。

4. Maven 依賴

以下是 RestTemplate 和 HttpClient 庫所需的 Maven 依賴:

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

<dependency>
   <groupId>org.apache.httpcomponents.client5</groupId>
   <artifactId>httpclient5</artifactId>
   <version>5.3</version>
</dependency>

5. 結論

本教程演示瞭如何設置和配置 Rest Template,以便它可以消費使用 Digest 身份驗證保護的應用程序。 REST API 本身也需要配置 Digest 安全機制。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.