繁体   English   中英

获取由Visual Studio在VSIX项目中存储的Nuget凭据

[英]Get Nuget credentials stored somewhere by Visual Studio in a VSIX project

我正在开发一个Visual Studio扩展(VSIX项目),该扩展需要管理给定项目的Nuget包。

我已经在使用此处记录IVsPackageInstaller服务,但这是有限的,并且我需要更多功能(例如,获取给定软件包的最新版本号)。

我进行了搜索,但没有找到有关如何与Visual Studio Package Manager进行编程交互的任何信息,因此我决定直接使用Nuget API。

我使用WebRequest类将HTTP请求发送到Nuget API(因为我们无法在VSIX项目中使用HttpClient ),但是我遇到了一个问题:请求将进入需要身份验证的私有Nuget提要! (托管在Azure DevOps上)

我使用Fiddler来检查发送到我们的Azure DevOps服务器的HTTP请求。 我看到带有令牌的POST请求转到https://app.vssps.visualstudio.com/_apis/Token/SessionTokens ,但这不是我要查找的令牌。

传递给Nuget API的令牌是Basic令牌,该令牌来自我不知道在哪里。 我在捕获的HTTP响应中的任何地方都找不到此令牌。

我还可以看到,对我们的Azure DevOps服务器的某些响应包含一些这样的标头(我更改了GUID)

WWW-Authenticate: Bearer authorization_uri=https://login.windows.net/ce372fcc-5e17-490b-ad99-47565dac8a84

我可以在%userprofile%\\AppData\\Local\\.IdentityService\\AccountStore.json文件中找到该GUID,这里肯定存在某些情况。 同样,该文件夹中的SessionTokens.json文件看起来也很有趣,但是它已经加密了...

我还尝试在注册表中进行挖掘,看看是否可以在例如Simon的注释中指定的路径中找到有趣的信息,但是VS2017似乎不再在其中存储令牌。

我还加载了privateregistry.bin文件(又名Visual Studio Settings Store ),并在各处搜索,但找不到任何内容。

因此,我不想直接对Visual Studio进行反向工程,而是想直接访问其凭据提供程序。 我试图访问一些服务和课程

var componentModel = await ServiceProvider.GetGlobalServiceAsync(typeof(SComponentModel)) as IComponentModel;
var credentialProvider = componentModel.GetService<IVsCredentialProvider>();
var credentialServiceProvider = componentModel.GetService<ICredentialServiceProvider>();
var defaultCredentialServiceProvider = new DefaultVSCredentialServiceProvider();

但是它们都不起作用(返回null或Exception)。

我在Github上的NuGet.PackageManagement.VisualStudio项目中徘徊,但找不到答案。

还有很多Nuget包,例如NuGet.PackageManagement.VisualStudioMicrosoft.VisualStudio.Services.Release.ClientMicrosoft.VisualStudio.Services.ExtensionManagement.WebApiMicrosoft.VisualStudio.Services.InteractiveClient仅举几个例子,但老实说,我没有不知道我在找什么...

那么如何访问Visual Studio使用的Nuget凭据?

我采用的任何解决方案都可以让我访问所有读取的Nuget功能,例如以编程方式使用Visual Studio程序包管理,或解密此SessionTokens.json文件或访问Visual Studio凭据提供程序。

越少哈克是答案,更好的是淡然的。

此时,您可能已经猜到了,我不想将usernamepassword存储在我自己的某个位置。 我需要创建一个用户友好的VS扩展,这就是为什么我要检索和使用用户已保存在Visual Studio中的凭据的原因。

非常感谢,如果您能解决这个问题。

NuGet客户端SDK

非常感谢Simon向我指出了NuGet.Client的方向

Microsoft唯一文档是链接Dave Glick2016年博客文章,但它们也给出了一个很好的注释:

这些博客文章是在发布3.4.3版本的NuGet客户端SDK软件包后不久写的。 软件包的较新版本可能与博客文章中的信息不兼容。

好吧,那么我想我们将与Dave的博客合作...

您应该安装两个软件包: NuGet.ClientNuget.Protocol

然后,这里是例如获取软件包最新版本的代码:

using NuGet.Configuration;
using NuGet.Protocol;
using NuGet.Protocol.Core.Types;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace MyProject
{
    public class NugetHelper
    {
        public async Task<string> GetLatestVersionNumberFromNugetFeedAsync(NugetPackage package)
        {
            try
            {
                Logger logger = new Logger(); //Just a class implementing the Nuget.Common.ILogger interface
                List<Lazy<INuGetResourceProvider>> providers = new List<Lazy<INuGetResourceProvider>>();
                providers.AddRange(Repository.Provider.GetCoreV3());  // Add v3 API support
                PackageSource packageSource = new PackageSource(package.Source.ToString());
                SourceRepository sourceRepository = new SourceRepository(packageSource, providers);
                PackageMetadataResource packageMetadataResource = await sourceRepository.GetResourceAsync<PackageMetadataResource>();
                var searchMetadata = await packageMetadataResource.GetMetadataAsync(package.Name, false, false, new SourceCacheContext(), logger, new CancellationToken());
                var versionNumber = searchMetadata.FirstOrDefault().Identity.Version.OriginalVersion;
                return versionNumber;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
    }

    public class NugetPackage
    {
        public string Name { get; set; }
        public string Version { get; set; }
        public string MinimumVersion { get; set; }
        public Uri Source { get; set; }
    }
}

物理令牌存储位置

我试图对Visual Studio进行反向工程的位置进行了存储,其中Visual Studio将存储在HTTP请求中向Nuget API使用的令牌。

我将注册表的所有不同配置单元(包括Visual Studio设置存储( privateregistry.bin ))导出到文本文件。 然后在Visual Studio中添加了全新的Nuget提要,如预期般出现了登录弹出窗口,因此我登录了。最后,我将所有配置单元再次导出到文本文件,并将它们与身份验证之前的文件进行了比较。

我在VS设置存储中没有发现任何有趣的东西。

唯一有趣的变化是

[HKEY_CURRENT_USER \\ Software \\ Microsoft \\ VSCommon \\ ConnectedUser \\ IdeUserV2] @ =“ 0746fb8e-4bc2-4ee5-b804-0084af725deb”“ AccountsRoaming_LastAccountsSettingVersion” = dword:0000025b

[HKEY_CURRENT_USER \\ Software \\ Microsoft \\ VsHub \\ ServiceModules \\ Settings \\ PerHubName \\ vshub \\ ConnectedUser \\ IdeUserV2 \\ Cache]“ LastProfileVersion” = dword:10b8260a

[HKEY_USERS \\ S-1-5-21-1787888774-1556370510-3519259403-1001 \\ Software \\ Microsoft \\ VSCommon \\ Keychain]“ TokenStorageNameSpace” =“ VisualStudio”

[HKEY_USERS \\ S-1-5-21-1787888774-1556370510-3519259403-1001 \\ Software \\ Microsoft \\ VsHub \\ ServiceModules \\ Settings \\ PerHubName \\ vshub \\ ConnectedUser \\ IdeUserV2 \\ Cache]“ LastProfileVersion” = dword:10b8260a

也许在某个地方,这些加密的SessionTokens.jsonIdentityServiceAdalCache.cache文件具有密钥,但是将数据存储为十六进制会使事情变得更加困难。

我不得不放弃这一点,几乎没有机会对认证系统进行反向工程。

Visual Studio凭据提供程序

NuGet Client SDK解决了我的问题,但实际上并未回答该SO问题。

正如我所说,我试图打电话

var componentModel = await ServiceProvider.GetGlobalServiceAsync(typeof(SComponentModel)) as IComponentModel;
componentModel.GetService<ICredentialServiceProvider>()

但这是行不通的,因此,如果有人知道如何访问Visual Studio凭据提供程序,我将非常高兴知道答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM