【问题标题】:non https VssConnection with access token - disable required secure connection?带有访问令牌的非 https VssConnection - 禁用所需的安全连接?
【发布时间】:2021-08-25 17:06:38
【问题描述】:

在我们的内部网络中使用 TFS,希望通过访问令牌以编程方式检查更改,但得到以下信息: InvalidOperationException 基本身份验证需要与服务器的安全连接。有没有办法关闭需要安全连接?

var basicCreds = new VssBasicCredential(string.Empty, BuildUnitTestConstants.AccessToken);
var connection = new VssConnection(new Uri(BuildUnitTestConstants.ProjectUri), basicCreds);
var sourceControlServer = connection.GetClient<TfvcHttpClient>();

【问题讨论】:

  • 您可以只使用 Windows 身份验证而不是 PAT 吗?启用不安全的基本身份验证是一个非常糟糕的主意,因为凭据是以明文形式传输的。
  • 知道了,这是在我们的 tfs 构建过程结束时它是一个临时令牌,但我理解他们为什么不想允许非安全...

标签: tfs


【解决方案1】:

嗯,这是可能的,尽管不推荐;我也需要它,因为内部 IT 部门不会使用 HTTPS 安装 TFS(可悲的故事)。此外,对于测试场景,它可以派上用场。

与往常一样,YMMV 我不对你不应该使用它时发生的事情负责;-) 你已被警告过。

你可以不使用 .NET 客户端 API,而直接使用 HttpClient 并手动将 PAT 放入 URL 以访问 REST API,例如:

 http://<WHATEVER>:<BASE64PAT>@<instance>/_apis/...

(因此tfx-cli 可以很好地与 PAT 和非 HTTPS TFS 实例配合使用,很可能是因为它只是在内部执行此操作,当然不使用 .NET 客户端 API - 这是一个 node.js 的东西。)

如果您想继续使用 .NET 客户端 API,您可以像这样创建自己的凭据类:

using System;
using System.Linq;
using System.Net;
using Microsoft.VisualStudio.Services.Common;

namespace Utilities
{
    /// <summary>
    /// Same as VssBasicCredential, but doesn't throw when URL is a non SSL, i.e. http, URL.
    /// </summary>
    /// <inheritdoc cref="FederatedCredential"/>
    internal sealed class PatCredentials : FederatedCredential
    {
        public PatCredentials()
            : this((VssBasicToken)null)
        {
        }

        public PatCredentials(string userName, string password)
            : this(new VssBasicToken(new NetworkCredential(userName, password)))
        {
        }

        public PatCredentials(ICredentials initialToken)
            : this(new VssBasicToken(initialToken))
        {
        }

        public PatCredentials(VssBasicToken initialToken)
            : base(initialToken)
        {
        }

        public override VssCredentialsType CredentialType => VssCredentialsType.Basic;

        public override bool IsAuthenticationChallenge(IHttpResponse webResponse)
        {
            if (webResponse == null ||
                webResponse.StatusCode != HttpStatusCode.Found &&
                webResponse.StatusCode != HttpStatusCode.Found &&
                webResponse.StatusCode != HttpStatusCode.Unauthorized)
            {
                return false;
            }

            return webResponse.Headers.GetValues("WWW-Authenticate").Any(x => x.StartsWith("Basic", StringComparison.OrdinalIgnoreCase));
        }

        protected override IssuedTokenProvider OnCreateTokenProvider(Uri serverUrl, IHttpResponse response)
        {
            return new BasicAuthTokenProvider(this, serverUrl);
        }

        private sealed class BasicAuthTokenProvider : IssuedTokenProvider
        {
            public BasicAuthTokenProvider(IssuedTokenCredential credential, Uri serverUrl)
                : base(credential, serverUrl, serverUrl)
            {
            }
            protected override string AuthenticationScheme => "Basic";
            public override bool GetTokenIsInteractive => this.CurrentToken == null;
        }
    }
}

然后使用这个类创建你的 VssCredentials:

var credentials = new PatCredentials("", personalAccessToken);
var connection = new VssConnection(serverUrl, credentials);

(无耻插件我用在我的TfsInfoService)。

【讨论】:

  • 好的,这行得通。它伤害了我的核心,但它有效。
  • @jessehouwing 哦,是的,“伤害我的核心”在不关心必需品的大部队中经常发生。
【解决方案2】:

现在您不需要使用@Christian.K 提供的解决方法

只需设置以下环境变量:

VSS_ALLOW_UNSAFE_BASICAUTH=true

来源:Microsoft.VisualStudio.Services.Common.VssBasicCredential的代码:

    protected override IssuedTokenProvider OnCreateTokenProvider(
      Uri serverUrl,
      IHttpResponse response)
    {
      bool result;
      if (serverUrl.Scheme != "https" && (!bool.TryParse(Environment.GetEnvironmentVariable("VSS_ALLOW_UNSAFE_BASICAUTH") ?? "false", out result) || !result))
        throw new InvalidOperationException(CommonResources.BasicAuthenticationRequiresSsl());
      return (IssuedTokenProvider) new BasicAuthTokenProvider(this, serverUrl);
    }

以编程方式设置环境变量:

Environment.SetEnvironmentVariable("VSS_ALLOW_UNSAFE_BASICAUTH", "true")

【讨论】:

  • 这简化了事情
  • @Mugen 它有效。谢谢。这应该是解决问题的答案。请添加 c# 命令设置环境变量:Environment.SetEnvironmentVariable("VSS_ALLOW_UNSAFE_BASICAUTH", "true");
【解决方案3】:

不,这是不可能的。在不安全的连接上启用 PAT 的问题在于,任何人都可以轻松拦截令牌,并将其用于自己的目的。

在 TSF 实例上启用 SSL,强烈建议这样做。或者使用 Windows 身份验证通过不安全的通道对 TFS 使用安全形式的身份验证。

【讨论】:

    猜你喜欢
    • 2010-10-13
    • 2019-04-02
    • 2018-04-07
    • 2014-10-30
    • 2019-06-19
    • 2011-11-15
    • 1970-01-01
    • 1970-01-01
    • 2019-07-23
    相关资源
    最近更新 更多