Azure移动服务LoginAsync方法不适用于Microsoft Auth令牌 [英] Azure Mobile Services LoginAsync method not working with Microsoft Auth Token
问题描述
我已经能够使用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屋!