Работаю над созданием бота, который будет отправлять письма с почты 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;
}
}
}
Технически, можно было бы просто сохранённый токен вернуть (если он уже сохранен) в методе GetAccessToken у провайдера, да вот только скорее всего ничего из этого не выйдет (вернее выйдет пока будете разрабатывать, а вот в боевых условиях все сломается), потому что у токена есть время жизни и в том же методе GetAccessToken есть процедура обновления токена по аккаунту и надо в базу сохранить именно этот аккаунт.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
помогите решить проблемуНеобходимо передать спрайт с объекта находящегося в магазине на объект, находящийся на другой сцене
Хотите улучшить этот вопрос? Обновите вопрос так, чтобы он вписывался в тематику Stack Overflow на русском
Поставили задачу написать алгоритм сложения элементов массива на asm(ассемблерные вставки на с),c#,c и сравнить время исполненияНаписал простенький...