簡體   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