无法从 Docker 容器内查询受 NTLM 保护的 API

问题描述 投票:0回答:1

我们正在构建一个

Worker
服务,我们希望将其托管在 Docker 容器中。该容器与我们的本地 SharePoint 服务器的 REST API 进行交互。 SharePoint REST API 中的身份验证使用 Windows 身份验证。

当我从 Visual Studio Code 运行下面的代码(在我的 Windows 开发计算机上使用

dotnet run
)时,代码可以正常运行,不会引发异常。

var opts = new RestClientOptions("https://sharepoint.domain.local");
opts.Credentials = new NetworkCredential("username", "password", "domain.local");

var spclient = new RestClient(opts);

var req = new RestRequest("_api/lists/getbytitle('MY_LIST')/items", Method.Get);

var resp = spclient.Execute(req);
_logger.LogDebug("Status code {x} returned from API call {y}", resp.StatusCode, resp.ResponseUri);
_logger.LogTrace("Raw response from {url}. Content: {raw}", resp.ResponseUri, resp.Content);

if(!resp.IsSuccessful)
{
    throw new Exception();
}

现在,当我在 Docker 容器中运行相同的代码时,API 调用失败,并且我从 SharePoint REST API 获取

Unauthorized
状态代码,并具有以下 JSON 响应:

{
  "odata.error": {
    "code": "-2147024891, System.UnauthorizedAccessException",
    "message": {
      "lang": "en-US",
      "value": "Access denied. You do not have permission to perform this action or access this resource."
    }
  }
}

出于测试目的,我使用与在开发计算机上使用的相同的用户名/密码。我确定提供了用户名和密码并且不为空。

更新

我还尝试使用以下代码指定

NTLM
。行为没有改变:

CredentialCache cc = new CredentialCache();
cc.Add("https://sharepoint.domain.local", "NTLM", "username", "password", "domain.local");


var opts = new RestClientOptions("https://sharepoint.domain.local");
opts.Credentials = cc;

var spclient = new RestClient(opts);

var req = new RestRequest("_api/lists/getbytitle('MY_LIST')/items", Method.Get);

var resp = spclient.Execute(req);
_logger.LogDebug("Status code {x} returned from API call {y}", resp.StatusCode, resp.ResponseUri);
_logger.LogTrace("Raw response from {url}. Content: {raw}", resp.ResponseUri, resp.Content);

if(!resp.IsSuccessful)
{
    throw new Exception();
}

请问有什么想法可以让它发挥作用吗?

docker .net-core restsharp ntlm-authentication
1个回答
0
投票

如果其他人遇到此问题,您需要将一些库添加到容器映像中才能正常工作。首先,从这段代码开始:

var opts = new RestClientOptions("https://sharepoint.domain.local");
opts.Credentials = new NetworkCredential("username", "password", "domain.local");

var spclient = new RestClient(opts);

var req = new RestRequest("_api/lists/getbytitle('MY_LIST')/items", Method.Get);

var resp = spclient.Execute(req);
_logger.LogDebug("Status code {x} returned from API call {y}", resp.StatusCode, resp.ResponseUri);
_logger.LogTrace("Raw response from {url}. Content: {raw}", resp.ResponseUri, resp.Content);

if(!resp.IsSuccessful)
{
    throw new Exception();
}

接下来,构建一个具有类似内容的

Dockerfile

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /source

# copy csproj and restore as distinct layers
COPY ./src .
RUN dotnet restore

# publish app and libraries
RUN dotnet publish -c release -o /app

# final stage
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app

# Install necessary packages for NTLM/Kerberos
RUN apt-get update && apt-get install -y libkrb5-3 libgssapi-krb5-2 gss-ntlmssp && rm -rf /var/lib/apt/lists/*

# Create the ./logs directory
RUN mkdir -p ./logs

COPY --from=build /app .
ENTRYPOINT [ "dotnet", "my.application.dll" ]
© www.soinside.com 2019 - 2024. All rights reserved.