2016-10-01 51 views
2

我有一个基于Xamarin的应用程序,它使用版本为1.x的Microsoft.OneDriveSDK nuget Package。在此应用程序中,我使用Xamarin.Auth管理OAuth内容,从而从该框架获取access_token。如何将Microsoft.OneDriveSDK v1迁移到v2?

使用OneDriveSDK 1.x,我可以通过重新定义几个类来提供此访问令牌,然后从不尝试获取令牌。

现在我想迁移到版本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

现在使用谷歌此消息总是说的记号不兼容智威汤逊,然后SDK将使用它作为微软的真实帐户令牌。但是,如果是这样的话,我想知道为什么它在V2中失败,但是在V1中起作用。

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

任何帮助非常感谢密歇根州:

认证是针对完成了!

回答

3

我使用子类Xamarin.Auth WebRedirectAuthenticatorMicrosoft.OneDriveSDK v2.0.0。

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()); 
} 

一旦我拥有的访问和刷新令牌,我可以实现,需要传递给OneDriveClient构造在IHttpProvider

我使用的是通过建立一个authorizeUrl:经由Xamarin.Auth子获得初始access_token为了设置访问令牌在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客户端和IHttpProvider对象(我只是在构建所有OneDrive API调用的相同类上实现它们),并且每个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,我希望有一种方法不像C#OneDrive SDK那样使用Graph,就像你可以用他们的Android版本一样。但跳过使用它登录,只实现两个接口工作正常。幸运的是,xamarin链接器去掉了所有未使用的Graph代码,并且应用程序的大小是可管理的 – SushiHangover