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的主要内容,如果未能解决你的问题,请参考以下文章