Azure 移动服务 LoginAsync 方法不适用于 Microsoft Auth Token

Posted

技术标签:

【中文标题】Azure 移动服务 LoginAsync 方法不适用于 Microsoft Auth Token【英文标题】:Azure Mobile Services LoginAsync method not working with Microsoft Auth Token 【发布时间】:2017-08-23 16:08:33 【问题描述】:

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

上面的代码 sn-p 用于获取我的用户详细信息。现在,当我尝试在后续调用中使用相同的令牌时,我得到一个 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】:

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

然后,我检查了有关 Authenticate users 的 Azure 移动应用的托管客户端。对于客户端管理的身份验证流程,我发现有关使用 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:

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

查看authentication with Microsoft Graph 时,我只能找到access_token 而不是AuthenticationToken

更新:

我已经通过 Fiddler 检查了 LiveLogin for WP8 和 Microsoft Account Authentication for Mobile Apps 以捕获授权请求。我发现MS账号认证和Live SDK有类似的授权请求。

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

更新 2:

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

【讨论】:

谢谢布鲁斯。你能解决问题吗?如果是这样,你能分享一下代码吗?特别是,我对使用哪些库来使用 LiveLoginResult 感到困惑。 谢谢布鲁斯。我注意到您使用了 response_type=code 而不是 response_type=token。获得代码后,您是否会在单独的调用中获得令牌?我问的原因是我需要令牌在 LoginAsync 调用中将其发送回。 是的,我只是捕获了单个请求...在调用LiveLoginResult loginResult=await this.authClient.LoginAsync(scopes); 之后,您可以从 loginresult 中检索 access_token。更多详情可以参考here。 你解决了这个问题吗?我找到了一些有用的信息,你可以看到我的更新。 嗨布鲁斯。我仍然没有运气...您可以发布您使用的实际代码吗?我也尝试过使用 Microsoft.Graph,但我得到了基本相同的 401 错误。

以上是关于Azure 移动服务 LoginAsync 方法不适用于 Microsoft Auth Token的主要内容,如果未能解决你的问题,请参考以下文章

Azure 移动服务推送不起作用

推送通知 Azure 移动服务(自托管)

Azure 移动服务(推送通知)

Azure 移动应用服务器在 GET 上不返回 DBGeography

将文件从 Azure 存储 blob 移动到 Ftp 服务器

Azure 移动服务中的随机 503 错误