Azure移动服务LoginAsync方法不适用于Microsoft Auth令牌 [英] Azure Mobile Services LoginAsync method not working with Microsoft Auth Token

查看:57
本文介绍了Azure移动服务LoginAsync方法不适用于Microsoft Auth令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

这是我的代码:

 私有异步System.Threading.Tasks.Task< string>MSGetUserInfo(帐户帐户){//参考:http://graph.microsoft.io/en-us/docs/overview/call_api//请注意,Microsoft无法识别access_token标头条目,而是依赖于Authorization标头条目var client = new HttpClient();var userInfoRequest = new HttpRequestMessage(){RequestUri =新的Uri("https://graph.microsoft.com/v1.0/me"),方法= HttpMethod.Get,};//添加访问承载userInfoRequest.Headers.Authorization =新的System.Net.Http.Headers.AuthenticationHeaderValue("Bearer",account.Properties ["access_token"]);;使用(var response = await client.SendAsync(userInfoRequest).ConfigureAwait(false)){如果(response.IsSuccessStatusCode){Models.User用户=新的Models.User();var responseString =等待响应.Content.ReadAsStringAsync().ConfigureAwait(false);var jobject = JObject.Parse(responseString);var userName =(string)jobject ["userPrincipalName"];//检查用户名是否有效如果(String.IsNullOrEmpty(userName)){抛出新的异常(未为经过身份验证的用户设置用户名");}别的user.ProviderLoginId = userName;var userDisplayName =(string)jobject ["displayName"];//如果无效,请替换显示名称如果(String.IsNullOrWhiteSpace(userDisplayName)){userDisplayName = userName;}别的user.Name = userDisplayName;var userEmail =(string)jobject ["mail"];//如果无效则替换电子邮件如果(String.IsNullOrWhiteSpace(userEmail)){userEmail = userName;}别的user.Email = userEmail;Valufy.App.currentUser =用户;}别的{抛出新的Exception("OAuth2请求失败:" +等待响应.Content.ReadAsStringAsync().ConfigureAwait(false));}}返回成功";} 

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

 公共异步任务< bool>验证(字符串令牌){字符串消息= string.Empty;var success = false;JObject objToken =新的JObject();//objToken.Add("access_token,令牌);//对于facebook和googleobjToken.Add("authenticationToken",令牌);//对于微软尝试{//使用服务器管理的流程以Facebook登录名登录.如果(用户==空){//ProviderAuth("MICROSOFT");用户=等待syncMgr.CurrentClient.LoginAsync(MobileServiceAuthenticationProvider.MicrosoftAccount,objToken);如果(用户!= null){成功=真;message = string.Format(您现在以{0}身份登录.",user.UserId);}}}抓住(前例外){message = string.Format(认证失败:{0}",例如Message);}//显示成功或失败消息.//等待新的MessageDialog(message,登录结果").ShowAsync();返回成功;} 

我在做错什么吗?感谢您的协助.

解决方案

根据您的描述,我遵循了

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

UPDATE2:

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

I have successfully been able to get an access_token (or authenticationToken for Microsoft tokens) using the client side authentication in my Xamarin forms App. I am able to get further user information (email, name, etc.) using the same access token. Now, when I try to pass that token to my Azure Mobile Service backend, I get a 401 error.

Here is my code:

        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";
    }

The above code snippet works in getting my user details. Now when I try to use the same token in the subsequent call, I get a 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;
    }

Is there something that I am doing wrong? Any and all assistance is appreciated.

解决方案

According to your description, I followed this Git sample about Microsoft Graph Connect Sample for UWP (REST). I could get the access_token and it could work as expected with Microsoft Graph API (e.g. Get a user). But when I use this access_token as the authenticationToken token object for MobileServiceClient.LoginAsync, I could also get 401 Unauthorized.

Then I checked the managed client for Azure Mobile Apps about Authenticate users. For Client-managed authentication flow, I found that the official code sample about using Microsoft Account is working with Live SDK as follows:

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

Note: As LiveConnectSession states about AuthenticationToken:

The authentication token for a signed-in and connected user.

While check the authentication with Microsoft Graph, I could only find the access_token instead of AuthenticationToken.

UPDATE:

I have checked LiveLogin for WP8 and Microsoft Account Authentication for Mobile Apps via Fiddler to capture the authorize requests. I found that MS account authentication has the similar authorize request as Live SDK.

I assumed that you need to leverage Live SDK to authenticate the user when using client side authentication with Microsoft account. I found the Live SDK download page is not exist, you could follow the Live SDK for WP8 to get started with Live SDK.

UPDATE2:

For the client-flow authentication (Microsoft Account), you could leverage MobileServiceClient.LoginWithMicrosoftAccountAsync("{Live-SDK-session-authentication-token}"), also you could use LoginAsync with the token parameter of the value {"access_token":"{the_access_token}"} or {"authenticationToken":"{Live-SDK-session-authentication-token}"}. I have tested LoginAsync with the access_token from MSA and retrieve the logged info as follows:

这篇关于Azure移动服务LoginAsync方法不适用于Microsoft Auth令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆