Azure移动服务LoginAsync方法无法使用Microsoft Auth Token

时间:2017-03-29 23:25:04

标签: oauth-2.0 xamarin.forms azure-mobile-services xamarin.auth xamarin.uwp

我已成功地在我的Xamarin表单应用程序中使用客户端身份验证获取access_token(或Microsoft令牌的authenticationToken)。我可以使用相同的访问令牌获取更多用户信息(电子邮件,姓名等)。现在,当我尝试将该令牌传递给我的Azure移动服务后端时,我收到401错误。

这是我的代码:

        private async System.Threading.Tasks.Task<string> MSGetUserInfo(Account account)
    {
        // Reference: http://graph.microsoft.io/en-us/docs/overview/call_api
        // Note that Microsoft don't recognize the access_token header entry, but rely instead on an Authorization header entry

        var client = new HttpClient();
        var userInfoRequest = new HttpRequestMessage()
        {
            RequestUri = new Uri("https://graph.microsoft.com/v1.0/me"),
            Method = HttpMethod.Get,
        };
        // Add acccess Bearer
        userInfoRequest.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", account.Properties["access_token"]);
        using (var response = await client.SendAsync(userInfoRequest).ConfigureAwait(false))
        {
            if (response.IsSuccessStatusCode)
            {
                Models.User user = new Models.User();
                var responseString = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                var jobject = JObject.Parse(responseString);
                var userName = (string)jobject["userPrincipalName"];
                // Check username is valid
                if (String.IsNullOrEmpty(userName))
                {
                    throw new Exception("Username was not set for authenticated user");
                }
                else
                    user.ProviderLoginId = userName;

                var userDisplayName = (string)jobject["displayName"];
                // Replace display name if invalid
                if (String.IsNullOrWhiteSpace(userDisplayName))
                {
                    userDisplayName = userName;
                }
                else
                    user.Name = userDisplayName;
                var userEmail = (string)jobject["mail"];
                // Replace email if invalid
                if (String.IsNullOrWhiteSpace(userEmail))
                {
                    userEmail = userName;
                }
                else
                    user.Email = userEmail;

                Valufy.App.currentUser = user;
            }
            else
            {
                throw new Exception("OAuth2 request failed: " + await response.Content.ReadAsStringAsync().ConfigureAwait(false));
            }
        }
        return "success";
    }

以上代码段用于获取用户详细信息。现在,当我尝试在后续调用中使用相同的令牌时,我得到一个404:

        public async Task<bool> Authenticate(string token)
    {
        string message = string.Empty;
        var success = false;
        JObject objToken = new JObject();
        //objToken.Add("access_token", token);  //for facebook and google
        objToken.Add("authenticationToken", token); //for microsoft

        try
        {
            // Sign in with Facebook login using a server-managed flow.
            if (user == null)
            {
                //ProviderAuth("MICROSOFT");
                user = await syncMgr.CurrentClient
                    .LoginAsync(MobileServiceAuthenticationProvider.MicrosoftAccount, objToken);
                if (user != null)
                {
                    success = true;
                    message = string.Format("You are now signed-in as {0}.", user.UserId);
                }
            }

        }
        catch (Exception ex)
        {
            message = string.Format("Authentication Failed: {0}", ex.Message);
        }

        // Display the success or failure message.
   //     await new MessageDialog(message, "Sign-in result").ShowAsync();

        return success;
    }

我做错了吗?任何和所有的帮助表示赞赏。

1 个答案:

答案 0 :(得分:0)

根据您的描述,我按照Git sample关于UWP(REST)的Microsoft Graph Connect示例进行了操作。我可以获得access_token,它可以按预期使用Microsoft Graph API(例如Get a user)。但是,当我使用此access_token作为authenticationToken的{​​{1}}令牌对象时,我还可以获得 401 Unauthorized

然后,我检查了Azure移动应用程序的托管客户端有关Authenticate users的信息。对于客户端管理的身份验证流程,我发现有关使用Microsoft帐户的官方代码示例正在使用Live SDK,如下所示:

MobileServiceClient.LoginAsync

注意:由于LiveConnectSession表示AuthenticationToken

  

已登录和已连接用户的身份验证令牌。

在查看authentication with Microsoft Graph时,我只能找到// Request the authentication token from the Live authentication service. // The wl.basic scope should always be requested. Other scopes can be added LiveLoginResult result = await liveIdClient.LoginAsync(new string[] { "wl.basic" }); if (result.Status == LiveConnectSessionStatus.Connected) { session = result.Session; // Get information about the logged-in user. LiveConnectClient client = new LiveConnectClient(session); LiveOperationResult meResult = await client.GetAsync("me"); // Use the Microsoft account auth token to sign in to App Service. MobileServiceUser loginResult = await App.MobileService .LoginWithMicrosoftAccountAsync(result.Session.AuthenticationToken); } 而不是access_token

<强>更新

我通过Fiddler检查了LiveLogin for WP8Microsoft Account Authentication for Mobile Apps以捕获授权请求。我发现MS帐户身份验证具有与Live SDK类似的授权请求。

enter image description here

我认为在使用Microsoft帐户进行客户端身份验证时,您需要利用Live SDK对用户进行身份验证。我发现Live SDK下载页面不存在,您可以按照Live SDK for WP8开始使用Live SDK。

<强> UPDATE2:

对于客户端流认证(Microsoft帐户),您可以使用AuthenticationToken,也可以将MobileServiceClient.LoginWithMicrosoftAccountAsync("{Live-SDK-session-authentication-token}")与值LoginAsync{"access_token":"{the_access_token}"}的令牌参数一起使用。我已使用MSA中的{"authenticationToken":"{Live-SDK-session-authentication-token}"}测试了LoginAsync,并按如下方式检索记录的信息: