4

我正在使用 Microsoft Graph C#.NET SDK 来访问用户的邮件收件箱。问题是,当我进行身份验证时,Microsoft 发回给我的令牌仅在 1 小时左右有效,而且过早过期。但是用户每 1 小时登录一次只是为了查看 Outlook 邮件收件箱,这太烦人了。我需要使这个登录持久化。

这是我使用的代码:

 public static async Task Run()
            {
                string secret = "MyDamnPrivateSecret";
                PublicClientApplication clientApp = new PublicClientApplication(secret);
                GraphServiceClient graphClient = new GraphServiceClient("https://graph.microsoft.com/v1.0", new DelegateAuthenticationProvider(async (requestMessage) =>
                {
                    requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", await GetTokenAsync(clientApp));
                }));
//Processing mailbox ...
            }

    private static async Task<string> GetTokenAsync(PublicClientApplication clientApp)
        {
            if (string.IsNullOrEmpty(Properties.Settings.Default.token) || string.IsNullOrWhiteSpace(Properties.Settings.Default.token))
            {
                //need to pass scope of activity to get token  
                string[] Scopes = { "User.Read", "Mail.ReadWrite" };
            string token = null;
            AuthenticationResult authResult = await clientApp.AcquireTokenAsync(Scopes);
            token = authResult.AccessToken;
            Properties.Settings.Default.token = token;
            Properties.Settings.Default.Save();
            return token;
            }
            else
            {
                return Properties.Settings.Default.token;
            }

        }

有什么办法可以延长过期时间吗?或者制作一个刷新令牌或其他东西来保持登录?

4

3 回答 3

3

您需要请求offline_access 范围以获取刷新令牌。如果您使用的是旧版本的 MSAL,则需要在构造函数中实现并传递令牌缓存PublicClientApplication,我认为 MSAL 将使用该缓存来自动刷新访问令牌。我认为较新的版本会为您处理 tokenCache。

从文档中,这是推荐的调用模式:首先尝试调用 AcquireTokenSilentAsync,如果失败并出现 MsalUiRequiredException,则调用 AcquireTokenAsync。

private static async Task<string> GetTokenAsync(PublicClientApplication clientApp)
    {
        AuthenticationResult result = null;

        try
        {
            string[] scopes = { "User.Read", "Mail.ReadWrite", "offline_access" };
            // Get the token from the cache.
            result = await app.AcquireTokenSilentAsync(scopes, clientApp.Users.FirstOrDefault());
            return result.AccessToken;
        }
        catch (MsalUiRequiredException ex)
        {
            // A MsalUiRequiredException happened on AcquireTokenSilentAsync. 
            // This indicates you need to call AcquireTokenAsync to acquire a token
            System.Diagnostics.Debug.WriteLine($"MsalUiRequiredException: {ex.Message}");

            try
            {
                // Dialog opens for user.
                result = await app.AcquireTokenAsync(scopes);
                return result.AccessToken;
            }
            catch (MsalException msalex)
            {
                ResultText.Text = $"Error Acquiring Token:{System.Environment.NewLine}{msalex}";
            }
        }
        catch (Exception ex)
        {
            ResultText.Text = $"Error Acquiring Token Silently:{System.Environment.NewLine}{ex}";
            return;
        }
    }

这是一个示例供参考。https://github.com/Azure-Samples/active-directory-dotnet-desktop-msgraph-v2

于 2018-09-18T21:51:39.017 回答
1

在您的代码AcquireTokenAsync中,总是触发登录。

相反,您需要实现令牌缓存并使用AcquireTokenSilentAsync.

有关更多信息,请查看以下链接:

Microsoft Graph SDK - 登录

于 2018-09-19T09:24:44.227 回答
1

我将尝试澄清这里的问题:

  1. MSAL .net 是为不同平台构建的 - .net 桌面、.net 核心、UWP、xamarin android 和 xamarin iOS。在其中一些平台(UWP 和 xamarin)上,我们会为您保留令牌缓存。在其他方面,我们希望您保留缓存。原因是我们无法提供适用于所有场景(例如 ASP.NET 服务器场)的令牌序列化逻辑,因此我们希望您这样做。我们为此提供样本和指导。MSAL wiki上的详细信息和一些参考实现:

  2. @Michael 提供的示例代码适用于 MSAL v1。在 MSAL v2 中,情况有些不同,您可以在MSAL wiki上找到调用模式:

  3. 我们请求并存储刷新令牌 (RT)。如果授权令牌 (AT) 已过期,我们将根据 RT 请求一个新令牌 - 这将在没有用户交互的情况下发生。这对你来说都应该是透明的,即它应该可以工作:)。确保您的令牌缓存序列化有效,即您在执行时获得一个帐户

// perform an interactive login first 
// otherwise there will be no AT / RT in the store
var accounts = await app.GetAccountsAsync();
// there should be an account that you can use
  1. 我们的大多数示例都展示了如何调用 Graph。在此处按场景查看所有示例。对于您的用例,我建议您查看从 WPF 应用程序调用图表

另请查看@Daniel Dobalian 对 AT 和 RT 默认到期的回答: MSAL 令牌在 1 小时后到期

于 2018-09-23T17:02:09.273 回答