バージョン1.xのMicrosoft.OneDriveSDKnugetパッケージを使用するXamarinベースのアプリケーションがあります。このアプリケーションでは、Xamarin.Authを使用してOAuthを管理し、そのフレームワークからaccess_tokenを取得します。
OneDriveSDK 1.xを使用すると、いくつかのクラスを再定義することでこのアクセストークンを提供でき、APIがトークンをフェッチしようとすることはありませんでした。
バージョン2に移行したいと思ったところ、以前のクラスが置き換えられ、APIが代わりにMicrosoft.Graphnugetパッケージを使用するようになりました。そのため、インターフェイス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では機能するのか疑問に思います。
認証は以下に対して行われます:
どんな助けでも大歓迎です!
サブクラス化されたXamarin.AuthWebRedirectAuthenticator
を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());
}
アクセストークンと更新トークンを取得したら、httpヘッダーにアクセストークンを設定するためにコンストラクターにIHttpProvider
渡す必要のあるものを実装OneDriveClient
できます。
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
を使用してクライアントを作成し(すべてのOneDrive API呼び出しを構築しているのと同じクラスに実装するだけです)、すべてのOnDrive要求は保存されたからのアクセストークンを使用します。IAuthenticationProvider
IHttpProvider
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;
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加