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
用作authenticationToken
的MobileServiceClient.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 移动应用服务器在 GET 上不返回 DBGeography