Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net EWS&x2B;MSAL和存储OAuth令牌以供以后使用_.net_Oauth 2.0_Azure Active Directory_Exchangewebservices_Msal - Fatal编程技术网

.net EWS&x2B;MSAL和存储OAuth令牌以供以后使用

.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邮箱交互,并

我需要有关如何检索存储的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)
);
}
}
}
}

我认为您想要的模式应该是:

  • 调用系统浏览器进行登录
  • 登录后返回非浏览器应用程序
  • 将生成的令牌存储在操作系统安全存储中
这是用于桌面应用程序的OAuth,即使桌面进程没有UI(对于控制台应用程序)

EWS应用程序是否作为其他应用程序的插件运行?如果是这样,您将需要使用桌面登录的环回变体

我有两个联机桌面示例,可以帮助您理解问题-您应该能够非常轻松地运行它们:

我也有一些详细的评论,从这里开始:

我的代码在Node.js中

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)
                                    );
            }
        }
    }
}