带有 Microsoft Graph 的 AuthProvider Api "Ctor not found"
AuthProvider with Microsoft Graph Api "Ctor not found"
我正在尝试使用 Microsoft.Graph Api 获取用户列表。我能够在 api 上进行身份验证。我在登录时收到令牌和基本个人资料信息。
然后我尝试使用 Microsoft.Graph.Auth SDK/nuget found 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()
时都得到错误System.MissingMethodException: 'Method not found: 'Void Microsoft.Graph.Auth.IntegratedWindowsAuthenticationProvider..ctor(Microsoft.Identity.Client.IPublicClientApplication, System.Collections.Generic.IEnumerable`1<System.String>)'.'
。该消息说它找不到 IntegratedWindowsAuthenticationProvider
但软件包已安装,我可以毫无问题地导航到构造函数 (F12)。
如果我删除带有 IntegratedWindowsAuthenticationProvider
的行,代码将执行而不会崩溃。而且我可以成功验证到 Api。我尝试在身份验证成功后移动线路,但出现相同的错误。
Microsoft.Graph.Auth 只支持.Net 4.5,我用的是4.8。由于代码库中的其他要求,我无法降级到 4.5。我试图修改开源项目,但我 运行 陷入其他问题,所以我决定不使用这个包。我实现了一个基本解决方案,其中包含一些自己管理令牌的方法。
这里是处理缓存令牌的class
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();
}
您所要做的就是 link 创建客户端应用程序构建器时的 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);
}
当然,根据您的要求添加 try catches 和 fail safes。
我正在尝试使用 Microsoft.Graph Api 获取用户列表。我能够在 api 上进行身份验证。我在登录时收到令牌和基本个人资料信息。
然后我尝试使用 Microsoft.Graph.Auth SDK/nuget found 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()
时都得到错误System.MissingMethodException: 'Method not found: 'Void Microsoft.Graph.Auth.IntegratedWindowsAuthenticationProvider..ctor(Microsoft.Identity.Client.IPublicClientApplication, System.Collections.Generic.IEnumerable`1<System.String>)'.'
。该消息说它找不到 IntegratedWindowsAuthenticationProvider
但软件包已安装,我可以毫无问题地导航到构造函数 (F12)。
如果我删除带有 IntegratedWindowsAuthenticationProvider
的行,代码将执行而不会崩溃。而且我可以成功验证到 Api。我尝试在身份验证成功后移动线路,但出现相同的错误。
Microsoft.Graph.Auth 只支持.Net 4.5,我用的是4.8。由于代码库中的其他要求,我无法降级到 4.5。我试图修改开源项目,但我 运行 陷入其他问题,所以我决定不使用这个包。我实现了一个基本解决方案,其中包含一些自己管理令牌的方法。
这里是处理缓存令牌的class
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();
}
您所要做的就是 link 创建客户端应用程序构建器时的 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);
}
当然,根据您的要求添加 try catches 和 fail safes。