Доступ к аккаунту Outlook с помощью токена

253
16 мая 2022, 17:20

Работаю над созданием бота, который будет отправлять письма с почты Outlook сразу в Телеграм. Для авторизации пользователя использую Microsoft Graph. Во время авторизации моя программа сохраняет токен доступа в базу данных для того, чтобы потом программа не запрашивала снова входить в систему при следующем запросе, а самостоятельно могла получить доступ к почте, используя токен. Но как авторизоваться в Outlook с помощью токена, без участия пользователя? Никак не могу найти. Подскажите, пожалуйста.

(Если нужно, вот процесс входа в аккаунт) :

var authProvider = new DeviceCodeAuthProvider(appId, scopes);
user.token = authProvider.GetAccessToken().Result;
GraphHelper.Initialize(authProvider);
micr_user = GraphHelper.GetMeAsync().Result;
public class DeviceCodeAuthProvider : IAuthenticationProvider
    {
        private IPublicClientApplication _msalClient; 
        private string[] _scopes;
        private IAccount _userAccount;
        public DeviceCodeAuthProvider(string appId, string[] scopes)
        {
            _scopes = scopes;
            _msalClient = PublicClientApplicationBuilder 
                .Create(appId)
                .WithAuthority(AadAuthorityAudience.AzureAdAndPersonalMicrosoftAccount, true) 
                .Build();
        }
        public async Task<string> GetAccessToken() 
        {
            // If there is no saved user account, the user must sign-in
            if (_userAccount == null)
            {
                try
                {
                    // Invoke device code flow so user can sign-in with a browser
                    var result = await _msalClient.AcquireTokenWithDeviceCode(_scopes, callback => {
                        Console.WriteLine(callback.Message);
                        return Task.FromResult(0);
                    }).ExecuteAsync();

                    _userAccount = result.Account;
                    return result.AccessToken;
                }
                catch (Exception exception)
                {
                    Console.WriteLine($"Error getting access token: {exception.Message}");
                    return null;
                }
            }
            else
            {
                // If there is an account, call AcquireTokenSilent
                // By doing this, MSAL will refresh the token automatically if
                // it is expired. Otherwise it returns the cached token.
                var result = await _msalClient
                    .AcquireTokenSilent(_scopes, _userAccount)
                    .ExecuteAsync();
                return result.AccessToken;
            }
        }
        
        // This is the required function to implement IAuthenticationProvider
        // The Graph SDK will call this function each time it makes a Graph call.
        public async Task AuthenticateRequestAsync(HttpRequestMessage requestMessage)
        {
            requestMessage.Headers.Authorization =
                new AuthenticationHeaderValue("bearer", await GetAccessToken());
            
        }
    }
public class GraphHelper
    {
        private static GraphServiceClient graphClient;
        public static void Initialize(IAuthenticationProvider authProvider)
        {
            graphClient = new GraphServiceClient(authProvider);
        }
        public static async Task<User> GetMeAsync()
        {
            try
            {
                return await graphClient.Me.Request().GetAsync();
            }
            catch (ServiceException ex)
            {
                Console.WriteLine($"Error getting signed-in user: {ex.Message}");
                return null;
            }
        }
}
Answer 1

Технически, можно было бы просто сохранённый токен вернуть (если он уже сохранен) в методе GetAccessToken у провайдера, да вот только скорее всего ничего из этого не выйдет (вернее выйдет пока будете разрабатывать, а вот в боевых условиях все сломается), потому что у токена есть время жизни и в том же методе GetAccessToken есть процедура обновления токена по аккаунту и надо в базу сохранить именно этот аккаунт.

READ ALSO
Передача sprite с одной сцены на другую Unity

Передача sprite с одной сцены на другую Unity

помогите решить проблемуНеобходимо передать спрайт с объекта находящегося в магазине на объект, находящийся на другой сцене

233
Найти минимальное количество подряд идущих максимальных элементов из данного набора [закрыт]

Найти минимальное количество подряд идущих максимальных элементов из данного набора [закрыт]

Хотите улучшить этот вопрос? Обновите вопрос так, чтобы он вписывался в тематику Stack Overflow на русском

157
сложение элементов массива через ассемблерные вставки

сложение элементов массива через ассемблерные вставки

Поставили задачу написать алгоритм сложения элементов массива на asm(ассемблерные вставки на с),c#,c и сравнить время исполненияНаписал простенький...

296
Помогите с регуляркой на C#!

Помогите с регуляркой на C#!

Есть регулярка, вот она:

171