.net EWS&x2B;MSAL和存储OAuth令牌以供以后使用
我需要有关如何检索存储的MSAL令牌的帮助,以便我可以在应用程序的执行过程中重用它 脚本: 下面我将介绍如何使用MSAL获取Oauth2令牌,以便在控制台应用程序中对EWS进行身份验证。它工作正常,每次运行应用程序时都会弹出一个交互式登录窗口来获取令牌 现在,我想在以后独立执行应用程序时使用相同的令牌(或其刷新令牌,如果原始令牌已过期) 最后,我想实现一个应用程序,用户通过我的web UI提供初始的交互式Oauth登录,从那时起,我为一个后台应用程序存储令牌,该应用程序与他们的EWS邮箱交互,并在需要时执行刷新 我正在尝试的是: 我一直在试图弄清楚这种基于本地文件的令牌缓存的概念。我可以看到它正在创建一个本地文件,但是如何让它在以后的执行中检查这个文件,并使用它存储在那里的标记。然后我找到了我的方法,但它没有文档,我甚至无法从它的测试中适应 我的代码: 帮助程序代码(来自“”).net EWS&x2B;MSAL和存储OAuth令牌以供以后使用,.net,oauth-2.0,azure-active-directory,exchangewebservices,msal,.net,Oauth 2.0,Azure Active Directory,Exchangewebservices,Msal,我需要有关如何检索存储的MSAL令牌的帮助,以便我可以在应用程序的执行过程中重用它 脚本: 下面我将介绍如何使用MSAL获取Oauth2令牌,以便在控制台应用程序中对EWS进行身份验证。它工作正常,每次运行应用程序时都会弹出一个交互式登录窗口来获取令牌 现在,我想在以后独立执行应用程序时使用相同的令牌(或其刷新令牌,如果原始令牌已过期) 最后,我想实现一个应用程序,用户通过我的web UI提供初始的交互式Oauth登录,从那时起,我为一个后台应用程序存储令牌,该应用程序与他们的EWS邮箱交互,并
静态类令牌缓存帮助器
{
公共静态void EnableSerialization(iTokeCache令牌缓存)
{
tokenCache.SetBeforeAccess(在accessnotification之前);
tokenCache.SetAfterAccess(AfterAccessNotification);
}
///
///令牌缓存的路径
///
公共静态只读字符串CacheFilePath=System.Reflection.Assembly.getExecutionGassembly().Location+“.msalcache.bin3”;
私有静态只读对象FileLock=新对象();
AccessNotification之前的私有静态无效(TokenCacheNotificationArgs args)
{
锁(文件锁)
{
args.TokenCache.DeserializeMsalV3(文件.Exists(缓存文件路径))
?ProtectedData.Unprotect(File.ReadAllBytes(CacheFilePath)),
无效的
DataProtectionScope.CurrentUser)
:空);
}
}
私有静态void AfterAccessNotification(令牌缓存通知args args args)
{
//如果访问操作导致缓存更新
如果(参数已更改)
{
锁(文件锁)
{
//在持久性存储中反映更改
File.writealBytes(缓存文件路径,
ProtectedData.Protect(args.TokenCache.SerializedSalv3(),
无效的
DataProtectionScope.CurrentUser)
);
}
}
}
}
我认为您想要的模式应该是:
- 调用系统浏览器进行登录
- 登录后返回非浏览器应用程序
- 将生成的令牌存储在操作系统安全存储中
static async System.Threading.Tasks.Task MainAsync(string[] args)
{
// Configure the MSAL client to get tokens
var pcaOptions = new PublicClientApplicationOptions
{
ClientId = ConfigurationManager.AppSettings["appId"],
TenantId = ConfigurationManager.AppSettings["tenantId"]
};
var pca = PublicClientApplicationBuilder
.CreateWithApplicationOptions(pcaOptions).Build();
TokenCacheHelper.EnableSerialization(pca.UserTokenCache); // added based on 'naive implementation'
var ewsScopes = new string[] { "https://outlook.office.com/EWS.AccessAsUser.All" };
try
{
// Make the interactive token request
var authResult = await pca.AcquireTokenInteractive(ewsScopes).ExecuteAsync(); // must have to change this to something else that is aware of the cache?
// Configure the ExchangeService with the access token
var ewsClient = new ExchangeService();
ewsClient.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
ewsClient.Credentials = new OAuthCredentials(authResult.AccessToken);
// Make an EWS call
// ... do stuff in EWS ...
}
}
static class TokenCacheHelper
{
public static void EnableSerialization(ITokenCache tokenCache)
{
tokenCache.SetBeforeAccess(BeforeAccessNotification);
tokenCache.SetAfterAccess(AfterAccessNotification);
}
/// <summary>
/// Path to the token cache
/// </summary>
public static readonly string CacheFilePath = System.Reflection.Assembly.GetExecutingAssembly().Location + ".msalcache.bin3";
private static readonly object FileLock = new object();
private static void BeforeAccessNotification(TokenCacheNotificationArgs args)
{
lock (FileLock)
{
args.TokenCache.DeserializeMsalV3(File.Exists(CacheFilePath)
? ProtectedData.Unprotect(File.ReadAllBytes(CacheFilePath),
null,
DataProtectionScope.CurrentUser)
: null);
}
}
private 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)
);
}
}
}
}