簡體   English   中英

Spring WebClient Windows NTLM 身份驗證

[英]Spring WebClient Windows NTLM Authentication

我找不到任何好的示例或文檔來清楚地解釋這一點。 我可以成功地使用(舊的)RestTemplate 進行身份驗證:

HttpClientBuilder httpClient = HttpClients.custom();
BasicCredentialsProvider provider = new BasicCredentialsProvider();
Credentials cred = new NTCredentials("my-user", "my-password", null, "my-domain");

provider.setCredentials(AuthScope.ANY, cred);
httpClient.setDefaultCredentialsProvider(provider);

HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.httpClient = httpClient.build();

RestTemplate restTemplate = new RestTemplate(request);

restTemplate.getForEntity("https://my.url.com", String.class)

我一直無法找到將NTCredentials (或Credentials )傳遞給 WebClient 的方法,已經嘗試過

WebClient client = WebClient.builder()
.filter(ExchangeFilterFunctions.basicAuthentication("user", "password"))
.build();

WebClient client = WebClient.builder().build();
client.get().headers(h -> h.setBasicAuth("user", "password"))...

但是這兩種方法都不適用於 WebClient

問題:

  1. 您如何使用 Spring WebClient 進行 Windows/NTLM 身份驗證?
  2. 無論如何,當使用當前用戶上下文在 Windows 中運行時,我是否可以在不提供用戶/密碼的情況下獲得 NTLM 或 Windows 身份驗證?

我最近一直在研究 Spring WebClient 的 NTLM。 首先,我嘗試使用 Apache HttpClient,但沒有得到任何響應。 我沒有進一步調查原因...

因為無論如何我都想使用 .netty HttpClient,所以我使用 JCIFS 實現實現了自己的ExchangeFilterFunction (與 Apache HttpClient 使用的相同)。 類似於:

public final class NtlmAuthorizedClientExchangeFilterFunction implements ExchangeFilterFunction {

    private final NtlmPasswordAuthentication ntlmPasswordAuthentication;
    private final boolean doSigning;

    public NtlmAuthorizedClientExchangeFilterFunction(String domain, String username, String password, boolean doSigning, int lmCompatibility) {
        this.ntlmPasswordAuthentication = new NtlmPasswordAuthentication(domain, username, password);
        this.doSigning = doSigning;
        System.setProperty("jcifs.smb.lmCompatibility", Integer.toString(lmCompatibility));
    }


    @Override
    public Mono<ClientResponse> filter(final ClientRequest request, final ExchangeFunction next) {
        NtlmContext ntlmContext = new NtlmContext(ntlmPasswordAuthentication, doSigning);
        try {
            return next.exchange(addNtlmHeader(request, ntlmContext.initSecContext(new byte[0], 0, 0)))
                .publishOn(Schedulers.single()) // this is necessary to make sure that the requests are processed sequential and thus http keep alive is working
                .flatMap(clientResponse -> {
                    List<String> ntlmAuthHeaders = getNtlmAuthHeaders(clientResponse);
                    if (ntlmAuthHeaders.isEmpty()) return Mono.error(...);
                    String ntlmHeader = ntlmAuthHeaders.get(0);
                    if (ntlmHeader.length() <= 5) return Mono.error(...);
                    try {
                        byte[] type2 = Base64.decode(ntlmHeader.substring(5));
                        return next.exchange(addNtlmHeader(request, ntlmContext.initSecContext(type2, 0, type2.length)));
                    } catch (IOException e) {
                        return Mono.error(...);
                    }
                });
        } catch (SmbException e) {
            return Mono.error(...);
        }
    }

    @NotNull
    private static List<String> getNtlmAuthHeaders(ClientResponse clientResponse) {
        List<String> wwwAuthHeaders = clientResponse.headers().header(HttpHeaders.WWW_AUTHENTICATE);
        List<String> ntlmAuthHeaders = wwwAuthHeaders.stream().filter(h -> h.startsWith("NTLM")).sorted(Comparator.comparingInt(String::length)).collect(Collectors.toList());
        return ntlmAuthHeaders;
    }

    private ClientRequest addNtlmHeader(ClientRequest clientRequest, byte[] ntlmPayload) {
        ClientRequest.Builder request = ClientRequest
            .from(clientRequest)
            .header(HttpHeaders.AUTHORIZATION, "NTLM ".concat(Base64.encode(ntlmPayload)));
        return request.build();
    }

你的第二個問題我沒有答案。 我的系統是 Linux。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM