使用ADAL.js获取令牌对Azure移动服务应用进行身份validation
我正在尝试针对Azure移动服务应用validationHTML应用。
安装程序
两个应用程序都使用AAD作为身份validation后端,因此两个应用程序都在Active Directory中注册了一个应用程序:
Azure移动服务应用:
- 按照https://azure.microsoft.com/en-gb/documentation/articles/mobile-services-how-to-register-active-directory-authentication/中的说明进行配置
- 我编辑了清单以启用客户端流程
- 为“Windows Azure Active Directory”启用“对其他应用程序的权限”下的“单点登录和读取用户配置文件”
HTML应用:
- 在“对其他应用程序的权限”中,我添加了具有委派权限“访问权限”的Azure移动服务应用程序
Azure移动服务使用.NET后端,我在其中包含并配置了NuGet包“Microsoft Azure移动服务.NET后端安全扩展”,如https://azure.microsoft.com/en-gb/documentation/articles/中所述。 移动服务- DOTNET -后端窗口电话-GET-开始用户/
HTML应用程序使用ADAL.JS和Angular:
adalAuthenticationServiceProvider.init( { // Config to specify endpoints and similar for your app clientId: "", redirectUri: "", endpoints: { '': 'https://ampapp.azure-mobile.net/' } }, $httpProvider );
此设置按预期工作,我打开我的HTML应用程序,对Azure AD进行身份validation,重定向到我的应用程序并且我已登录。此外,当我尝试访问我的Azure移动服务时,我看到Adal.js注入持有者令牌。
问题
Azure移动服务不接受承载令牌 – 我获得401未经授权。 我不知道为什么,但Azure移动服务使用它自己的身份validation标头 – 但没关系。
MSDN为Azure移动服务定义了一个所谓的“客户端定向登录操作”:
“通过使用已从身份提供商处获得的身份令牌,从Microsoft Azure Mobile Services请求身份validation令牌。” ( https://msdn.microsoft.com/en-us/library/azure/jj710106.aspx )
好的,所以我们这样做:
// obtain token for Azure Mobile Service from Adal.js var token = this.getAADToken(ZUMOAuthenticationProvider.Config().url); $http({ method: 'POST', url: ZUMOAuthenticationProvider.Config().url + 'login/aad', data: JSON.stringify({ "access_token" : token }), headers: { 'X-ZUMO-APPLICATION': '' }). success(function (data, status, headers, config) { alert(data); }). error(function (data, status, headers, config) { alert(data); });
注意:第一行获取的令牌实际上是azure移动服务aad应用程序的访问令牌,而不是HTML应用程序的访问令牌。
此POST请求也会收到401响应。 所以我不知道如何validation我的应用程序。 我也尝试过azure mobile service js lib。 这个lib工作,但是它使用弹出窗口进行身份validation,但是我不想在我的项目中添加另一个库来进行一些REST调用。
类似的问题
在尝试解决我的问题时,我发现了其他Stackoverflowpost:
为什么我的Azure移动服务不接受ADAL.js发送的承载令牌?
- 同样的问题,没有解决方案(甚至在最后评论中链接的聊天记录中)
如何使用Azure AD保护Azure移动服务? ADAL.JS
- 与上面的作者相同,我检查了接受的答案中提到的所有内容,但它不起作用
我还看了一下来自新Azure管理门户的新Azure Mobile应用程序,但似乎他们使用相同的身份validation机制。
那么,我怎样才能使这个工作?
好的,我发现了我的错误:
endpoints: { '': 'https://ampapp.azure-mobile.net/' }
这应该是
endpoints: { 'https://ampapp.azure-mobile.net/': '': }
在此之后它有效! 我发布了一个Angular模块到github,它将X-Auth-User标头中的标记注入到adal.js这样的每个请求中。
编辑:
正如这里所承诺的更详细的答案:
如我的问题所述,您必须在Azure Active Directory中设置2个应用程序:
- Azure移动服务的AAD应用程序
- 只需按照本文中的说明操作即可
- HTML应用程序的AAD应用程序
- 将“oauth2AllowImplicitFlow”设置为“true”
- 在“对其他应用程序的权限”下添加Azure移动服务AAD应用程序
配置Angular应用程序以将Azure Mobile服务用作端点
adalAuthenticationServiceProvider.init( { clientId:"54110492-4ae3-4c9f-9530-3101458d43fb", redirectUri: "https://localhost:44304/", endpoints: { 'https://zumodemoapp.azure-mobile.net/': 'https://zumodemoapp.azure-mobile.net/login/aad' } }, $httpProvider );
现在,您可以使用客户端控制的登录操作来获取Azure移动服务身份validation令牌。
var zumoAppID = 'https://zumodemoapp.azure-mobile.net/login/aad'; var zumoLoginUri = 'https://zumodemoapp.azure-mobile.net/login/aad'; var zumoTodoController = 'https://zumodemoapp.azure-mobile.net/tables/TodoItem'; // 1. acquire a oath token for our zumo app from azure ad via adal.js adalAuthenticationService.acquireToken(zumoAppID).then(function (data) { //2. we have the azure ad token, lets get a azure mobile service token $http.post(zumoLoginUri, JSON.stringify({ "access_token": data })). success(function (data, status, headers, config) { //3. with the azure mobile service token we can authenticate our request $http.get(zumoTodoController, { headers: { 'X-ZUMO-AUTH': data.authenticationToken } }). success(function (data, status, headers, config) { alert(data); //yay! }); }). error(function (data, status, headers, config) { alert(data); }); });
正如评论中提到的,我在这里创建了一个更详细的博客文章。 如果您需要更多信息,请发表评论:)。
您可以使用AzureMobileServices客户端脚本使用已获取的令牌进行登录:
您需要包含以下脚本: https : //ajax.aspnetcdn.com/ajax/mobileservices/MobileServices.Web-1.2.8.min.js
然后,在使用ADAL.JS获取令牌后,您可以使用它来登录并获取移动服务身份validation令牌:
var appUrl = 'https://foobar.azure-mobile.net' , appKey = 'zumo key' // found on the dashboard of the mobile service , client = new WindowsAzure.MobileServiceClient(appUrl, appKey); // ... var token = this.getAADToken(ZUMOAuthenticationProvider.Config().url); client .login('aad', { 'access_token': token }) .then(function() { // client.currentUser.mobileServiceAuthenticationToken });
然后,此令牌需要包含在后续的移动服务API请求中:
var config = { headers: { 'X-ZUMO-AUTH': client.currentUser.mobileServiceAuthenticationToken } } $http .get(appUrl + '/some/path', config) .then(function (r) { console.log(r); });
POST可能返回401,因为AAD令牌的受众不正确。 移动服务期望这是其/ login / aad端点,但我怀疑您发送的令牌实际上是作用于您呼叫的网站。 委派的访问权限只表示您可以从站点获取令牌并将其转换为移动服务的令牌。 它不会改变已发布令牌本身的性质。
因此,最好的建议是确保您已登录移动服务受众,或执行委派的访问流程。 不幸的是, 除非使用ADAL.NET,否则后者似乎没有太多样本
一种解决方法是在移动服务上设置MS_AadAudience应用程序设置以匹配您的网站。 只有在站点和移动服务存在于应用程序的同一逻辑安全边界内时,才应执行此操作。 也就是说,任何可以登录您网站的内容都可以访问移动服务。 总的来说,更好的方法是获得移动服务的访问令牌。