2016-10-01 2 views
2

У меня есть приложение на основе Xamarin, которое использует пакет Microsoft.OneDriveSDK nuget с версией 1.x. В этом приложении я управляю файлом OAuth с помощью Xamarin.Auth и тем самым получаю access_token из этой структуры.Как перенести Microsoft.OneDriveSDK v1 в v2?

С OneDriveSDK 1.x я мог бы предоставить этот токен доступа, переопределив несколько классов, а затем никогда не использовал API, пытающийся извлечь токен.

Теперь я хотел перейти на версию 2 и заметил, что предыдущие классы были заменены, и теперь API теперь использует пакет Microsoft.Graph nuget. Поэтому я должен был реализовать интерфейс IAuthenticationProvider и сделал это так:

public async Task AuthenticateRequestAsync(HttpRequestMessage request) 
    { 
     if (!string.IsNullOrEmpty(MicrosoftLiveOAuthProvider.Instance.AccessToken)) 
     { 
      request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("bearer", MicrosoftLiveOAuthProvider.Instance.AccessToken); 
     } 
    } 

код называется и правильно обеспечивает маркер аутентификации заголовков запроса. Но как только SDK пытается использовать токен, я получаю исключение:

Исключение типа «Microsoft.Graph.ServiceException» было выбрано.

Код: InvalidAuthenticationToken

Сообщение: CompactToken разбор неудачно с кодом ошибки: -2147184118

Теперь с помощью Google для этого сообщения всегда говорил, что маркер не JWT совместимый и SDK будет затем использовать его в качестве токен учетной записи Microsoft. Но если это так, я задаюсь вопросом, почему он не работает с V2, но работает с V1.

Аутентификация осуществляется против:

https://login.live.com/oauth20_authorize.srf

Любая помощь очень Mich оценили!

ответ

3

Я использую подклассу Xamarin.Auth WebRedirectAuthenticator с Microsoft.OneDriveSDK v2.0.0.

я получаю начальную access_token с помощью этого Xamarin.Auth подкласса с использованием authorizeUrl:, который построен с помощью:

string GetAuthorizeUrl() 
{ 
    var requestUriStringBuilder = new StringBuilder(); 
    requestUriStringBuilder.Append(Consts.MicrosoftAccountAuthenticationServiceUrl); 
    requestUriStringBuilder.AppendFormat("?{0}={1}", Consts.RedirectUriKeyName, Consts.Redirect_URI); 
    requestUriStringBuilder.AppendFormat("&{0}={1}", Consts.ClientIdKeyName, Consts.Client_ID); 
    requestUriStringBuilder.AppendFormat("&{0}={1}", Consts.ResponseTypeKeyName, Consts.TokenKeyName); 
    requestUriStringBuilder.AppendFormat("&{0}={1}", Consts.ScopeKeyName, Consts.Drive_Scopes); 
    return Uri.EscapeUriString(requestUriStringBuilder.ToString()); 
} 

После того, как у меня есть доступ и обновить маркера, я могу реализовать IHttpProvider, который нуждается в передаваемом в OneDriveClient конструктору чтобы установить маркер доступа в заголовке HTTP:

public Task<HttpResponseMessage> SendAsync(HttpRequestMessage request) 
{ 
    SetupHttpClient(); 
    return _httpClient.SendAsync(request); 
} 

public Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken) 
{ 
    SetupHttpClient(); 
    return _httpClient.SendAsync(request, completionOption, cancellationToken); 
} 

HttpClient _httpClient; 
void SetupHttpClient() 
{ 
    if (_httpClient == null) 
    { 
     _httpClient = new HttpClient(); 
     var accessToken = _account.Properties["access_token"]; 
     _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); 
    } 
} 

Создание своего клиента OneDriveClient помощью IAuthenticationProvider и IHttpProvider (я просто реализую их в том же классе, что и все вызовы API OneDrive), и каждый запрос OnDrive будет использовать токен доступа из сохраненного Account.

Примечание: В моем IAuthenticationProvider исполнении AuthenticateRequestAsync в настоящее время ничего не делается, но вы можете сделать свою настройку Account здесь для более чистого потока кода.

var oneDriveClient = new OneDriveClient("https://api.onedrive.com/v1.0", this, this); 
var pictureFolderItem = await oneDriveClient.Drive.Root.ItemWithPath("Pictures").Request().GetAsync(); 
Console.WriteLine(pictureFolderItem.Folder); 

Освежающий почти так же легко, я храню, когда маркер доступа истекает (минус 5 минут) и настроить таймер, чтобы обновить его и повторно сохранить его в Account. Сделайте то же самое при запуске приложения, если пользователь имеет Account доступны и, таким образом, ранее вошли в систему, проверить, если он истек, обновить его, установить фоновое таймер ...

async Task<bool> GetRefreshToken(Account account) 
{ 
    // https://github.com/OneDrive/onedrive-api-docs/blob/master/auth/msa_oauth.md#step-3-get-a-new-access-token-or-refresh-token 
    OneDriveOAuth2Authenticator auth = OAuth2Authenticator(); 
    var token = account.Properties["refresh_token"]; 
    var expiresIn = await auth.RequestRefreshTokenAsync(token); 
    ResetRefreshTokenTimer(expiresIn); 
    return true; 
} 
+0

Спасибо большое за нашли время для этого всеобъемлющего ответа! Тем временем я заметил, что в области, где я зарегистрировал приложение для OneDrive, теперь можно определить также разрешения Microsoft Graph, такие как делегирование и учетные данные приложения. Я уверен, что это тоже нужно будет установить. Кроме того, в описании указано, что конечная точка V2 Auth - это Azure AD или Microsoft Live. В настоящее время я проверяю подлинность только на Microsoft Live, поэтому основное преимущество MS Graph исчезло. – eX0du5

+0

Я использую Live acct для oauth2 против, мне жаль, что не было возможности использовать Graph с C# OneDrive SDK, как вы можете с их версией Android. Но пропуск с его использованием для входа в систему и реализация только двух интерфейсов прекрасно работает. К счастью, компоновщик xamarin удаляет весь неиспользуемый код Graph и размер приложения управляется – SushiHangover

Смежные вопросы