非https VssConnection与访问令牌 - 禁用所需的安全连接?

时间:2017-09-16 03:22:03

标签: tfs

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

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

3 个答案:

答案 0 :(得分:7)

嗯,有可能,尽管不推荐;我也需要它,因为内部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中使用它。)

答案 1 :(得分:5)

如今,您无需使用@ Christian.K提供的解决方法

只需设置以下env变量:

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);
    }

答案 2 :(得分:3)

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

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