【问题标题】:AuthProvider with Microsoft Graph Api "Ctor not found"带有 Microsoft Graph Api 的 AuthProvider“未找到 Ctor”
【发布时间】:2021-04-30 02:44:45
【问题描述】:

我正在尝试使用 Microsoft.Graph Api 获取用户列表。我能够在 api 上进行身份验证。登录时我会收到令牌和基本个人资料信息。

然后我尝试使用找到的 Microsoft.Graph.Auth SDK/nuget here 来生成我的请求。这是我正在尝试做的一个准系统示例(您也可以在包的文档中找到此示例。

public void test()
{
    var clientApplication = PublicClientApplicationBuilder
        .Create(ClientId)
        .WithTenantId(TenantId)
        .Build();

    var authProvider = new IntegratedWindowsAuthenticationProvider(clientApplication);
    var graphClient = new GraphServiceClient(authProvider);

    var users = await graphClient.Users
        .Request()
        .GetAsync();
}

但我得到错误System.MissingMethodException: 'Method not found: 'Void Microsoft.Graph.Auth.IntegratedWindowsAuthenticationProvider..ctor(Microsoft.Identity.Client.IPublicClientApplication, System.Collections.Generic.IEnumerable`1<System.String>)'.' 之前,甚至输入方法test()。消息说它找不到IntegratedWindowsAuthenticationProvider,但是安装了包,我可以毫无问题地导航到构造函数(F12)。

如果我删除带有IntegratedWindowsAuthenticationProvider 的行,代码将执行而不会崩溃。而且我可以成功地通过 Api 身份验证。我尝试在成功验证后移动线路,但我得到了同样的错误。

【问题讨论】:

    标签: c# oauth-2.0 microsoft-graph-api microsoft-graph-sdks


    【解决方案1】:

    Microsoft.Graph.Auth 只支持 .Net 4.5,我用的是 4.8。由于代码库中的其他要求,我无法降级到 4.5。我试图修改开源项目,但遇到了其他问题,所以我决定不使用这个包。我实现了一个基本解决方案,其中包含一些自己管理令牌的方法。

    这是处理缓存令牌的类

    using System.IO;
    using System.Security.Cryptography;
    using Microsoft.Identity.Client;
    
    namespace Overwatch.AutoCAD.Authentication
    {
        static class TokenCacheHelper
        {
            static TokenCacheHelper()
            {
                CacheFilePath = System.Reflection.Assembly.GetExecutingAssembly().Location + ".msalcache.bin3";
            }
    
            /// <summary>
            /// Path to the token cache
            /// </summary>
            public static string CacheFilePath { get; private set; }
    
            private static readonly object FileLock = new object();
    
            public static void BeforeAccessNotification(TokenCacheNotificationArgs args)
            {
                lock (FileLock)
                {
                    args.TokenCache.DeserializeMsalV3(File.Exists(CacheFilePath)
                            ? ProtectedData.Unprotect(File.ReadAllBytes(CacheFilePath),
                                                     null,
                                                     DataProtectionScope.CurrentUser)
                            : null);
                }
            }
    
            public static void AfterAccessNotification(TokenCacheNotificationArgs args)
            {
                // if the access operation resulted in a cache update
                if (args.HasStateChanged)
                {
                    lock (FileLock)
                    {
                        // reflect changesgs in the persistent store
                        File.WriteAllBytes(CacheFilePath,
                                           ProtectedData.Protect(args.TokenCache.SerializeMsalV3(),
                                                                 null,
                                                                 DataProtectionScope.CurrentUser)
                                          );
                    }
                }
            }
    
            internal static void EnableSerialization(ITokenCache tokenCache)
            {
                tokenCache.SetBeforeAccess(BeforeAccessNotification);
                tokenCache.SetAfterAccess(AfterAccessNotification);
            }
        }
    }
    

    这是我修改后的初始测试方法

    public async void test()
    {
        AuthenticationResult authResult = await PublicClientApp
            .AcquireTokenSilent(scopes, (await PublicClientApp.GetAccountsAsync()).FirstOrDefault())
            .ExecuteAsync();
        HttpClient client = ApiHelper.CreateHttpClient("https://graph.microsoft.com/v1.0/");
        GraphServiceClient graphClient = new GraphServiceClient(new DelegateAuthenticationProvider(async (requestMessage) =>
        {
            requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
        }));
    
        var users = await graphClient.Users
            .Request()
            .GetAsync();
    }
    

    您所要做的就是在创建客户端应用程序构建器时链接 TokenCache 助手

    public static void CreateApplication()
    {
        var builder = PublicClientApplicationBuilder.Create(ClientId)
            .WithAuthority($"{Instance}{Tenant}")
        .WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient");
    
        _clientApp = builder.Build();
    
        TokenCacheHelper.EnableSerialization(_clientApp.UserTokenCache);
    }
    

    当然,根据您的要求添加尝试捕获和故障保险。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-24
      • 2021-05-13
      • 1970-01-01
      • 2019-12-20
      • 2019-01-13
      • 2020-07-30
      相关资源
      最近更新 更多