Azure移动服务和Azure Web应用程序身份验证

5

当用户通过 Azure Web 应用程序(ASP.NET MVC)和 Xamarin.iOS 应用程序登录时,我会得到相同用户的两个不同 SID。

设置

Azure WebApp ASP.NET 5 带有 API 控制器

Xamarin iOS 应用程序使用 Microsoft.WindowsAzure.Mobile.Client SDK Azure B2C AAD

Web 上的用户

我获得的是 ObjectIdentifier 值,即 AAD SID:

var userClaim = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;

移动用户

我只获得了一个Nameidentifier值,没有ObjectIdentifier。

ClaimsPrincipal mobileUser = this.User as ClaimsPrincipal;
var mobileUserClaim = mobileUser.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier");

这里的SID是完全不同的,从移动端进行认证的用户获取到的SID为xxxx,而从Web端则获取到了xxx。

我知道如果我设置一个Azure Mobile App和一个Azure Web App,则在进行身份验证时SID将是相同的。但是由于我的应用程序很小,我不想管理两个站点。这个应用程序的目的是拥有一个简单的Web应用程序来执行一些动作,并且可以通过手机进行相同的操作。我使用Azure Mobile Service SDK和InvokeAPIAsync从手机上使用API控制器来调用Web App中的API。

谢谢

2个回答

1
我想澄清一下情况。 您正在观察两个SID:
1)通过Web浏览器登录AAD。
2)从Azure应用服务(Web应用程序和移动应用程序)中,可能是使用我们客户端的LoginAsync。这种方法将调用服务器定向的登录流程。
这是设计上的。MobileServiceClient获取App Service令牌,并使用该令牌对您的移动应用进行身份验证。您可以通过对.auth/me端点进行GET来交换从Azure App Service获得的auth令牌以获得AAD SID。
在客户端经过App Service和AAD身份验证后,您可以通过调用yoursite.azurewebsites.net/.auth/me并解析响应以获取所需声明来获取有关AAD用户(或任何身份提供者)的更多信息:
({"typ" : "http://schemas.microsoft.com/identity/claims/objectidentifier").

另一种策略是从客户端应用程序使用ADAL (http://www.nuget.org/packages/Microsoft.IdentityModel.Clients.ActiveDirectory/) 登录AAD,然后使用AAD访问令牌使用适当的LoginAsync重载来获取移动应用程序令牌:

https://github.com/Azure/azure-mobile-apps-net-client/blob/master/src/Microsoft.WindowsAzure.MobileServices.iOS/Extensions/MobileServiceClientExtensions.cs#L55

您添加的参数应该是这种格式:{"access_token":"[AAD访问令牌值]"}
Brett Samblanet关于.NET服务器上用户ID的维基页面可以帮助理解正在发生的情况: https://github.com/Azure/azure-mobile-apps-net-server/wiki/Understanding-User-Ids

感谢您抽出时间回答。我已经使用Token测试了您的示例,但是我使用的是bearer而不是access_token。今晚我会进行测试。谢谢。 - JCB
另一个问题:如果我从客户端(iOS应用程序)使用ADAL,我可以使用检索到的AAD AccessToken对我的WebApp API进行用户身份验证吗?我尝试过了,其中authResult.AccessToken是通过ADAL获取的AAD访问令牌。但是我从未能够对我的WebApp API进行身份验证,因为它显示未经授权。参数是否错误,而不是Bearer,它可能应该是access_token?今晚我会尝试一下。HttpClient client = new HttpClient(); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken); - JCB
@JCB 很抱歉让你等待了。不,你的AAD访问令牌不能用于对WebApp进行身份验证。你需要将其交换为一个AppService令牌。具体来说,请再次查看我在帖子末尾提到的LoginAsync()重载。其结果将是一个App Service令牌。 - Aziel
嗨Aziel,对不起我也耽搁了。一直没有时间尝试这个,但现在我已经试过了。当我使用LoginAsync重载时,我会得到一个弹出视图来登录AAD。Dictionary<string, string> msgDic = new Dictionary<string, string>(); msgDic.Add("access_token", authResult.AccessToken); await mobileServiceClient.LoginAsync(this, MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory, msgDic);如果成功登录并获得了App Service Token,那么在与Azure Web App的身份验证标头中,这个令牌应该是什么值,是Bearer吗?谢谢 - JCB

0
我终于搞定了:
string authority = "https://login.windows.net/[TentantId].onmicrosoft.com/";
            string resourceId = "[myApiClientId]";
            string clientId = "[clientId]";
            string redirectUri = "https://[URL]/.auth/login/done";

            AuthenticationContext ac = new AuthenticationContext(authority);
            AuthenticationResult ar = await ac.AcquireTokenAsync(resourceId, clientId,
                new Uri(redirectUri), new PlatformParameters(this));
            JObject payload = new JObject();
            payload["access_token"] = ar.AccessToken;

            string authHeader = ar.CreateAuthorizationHeader();
            HttpClient client = new HttpClient();
            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "[API URL Route]");
            request.Headers.TryAddWithoutValidation("Authorization", authHeader);
            HttpResponseMessage response = await client.SendAsync(request);
            string content = await response.Content.ReadAsStringAsync();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接