1

我已经成功地在我的 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;
    }

有什么我做错了吗?感谢您提供任何和所有帮助。

4

1 回答 1

0

根据您的描述,我遵循了这个关于 UWP 的 Microsoft Graph Connect 示例(REST)的Git 示例。我可以得到access_token它,它可以与 Microsoft Graph API 一起按预期工作(例如Get a user)。但是当我使用它access_token作为authenticationToken令牌对象时MobileServiceClient.LoginAsync,我也可以得到401 Unauthorized

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

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

注意:正如LiveConnectSession关于AuthenticationToken的状态:

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

在使用 Microsoft Graph检查身份验证时,我只能找到access_token而不是AuthenticationToken.

更新:

我已经通过 Fiddler 检查了 WP8 的 LiveLogin移动应用程序的 Microsoft 帐户身份验证,以捕获授权请求。我发现 MS 账户认证与 Live SDK 有类似的授权请求。

在此处输入图像描述

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

更新2:

对于客户端流身份验证(Microsoft 帐户),您可以利用MobileServiceClient.LoginWithMicrosoftAccountAsync("{Live-SDK-session-authentication-token}"),也可以与 value或LoginAsync的 token 参数一起使用。我已经使用来自 MSA 的测试并检索记录的信息,如下所示:{"access_token":"{the_access_token}"}{"authenticationToken":"{Live-SDK-session-authentication-token}"}LoginAsyncaccess_token

于 2017-04-01T08:24:04.237 回答