我正在试用adal.js的角度SPA (单页应用程序)网站,从外部的web网站(不同的领域)数据。adal.js很容易对SPA进行身份验证,但是当需要承载令牌时,让它与API通信根本不起作用。除了无数的博客之外,我还使用了https://github.com/AzureAD/azure-activedirectory-library-for-js作为模板。
问题是,当我在启动adal.js时设置端点时,adal.js似乎将所有传出端点流量重定向到microsofts登录服务。
意见:
我的理论是,adal.js无法为端点检索令牌(可能是因为我在SPA中配置了一些错误),并且由于它无法获得所需的令牌,所以它停止了对端点的通信。SPA令牌不能针对API使用,因为它不包含所需的权限。为什么adal.js没有为端点获取令牌,以及如何修复它?
其他信息:
会话存储:
key (for the SPA application): adal.access.token.keyxxxxx-b7ab-4d1c-8cc8-xxx value: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1u...
key (for API application): adal.access.token.keyxxxxx-bae6-4760-b434-xxx
value:app.js (角和adal配置文件)
(function () {
'use strict';
var app = angular.module('app', [
// Angular modules
'ngRoute',
// Custom modules
// 3rd Party Modules
'AdalAngular'
]);
app.config(['$routeProvider', '$locationProvider',
function ($routeProvider, $locationProvider) {
$routeProvider
// route for the home page
.when('/home', {
templateUrl: 'App/Features/Test1/home.html',
controller: 'home'
})
// route for the about page
.when('/about', {
templateUrl: 'App/Features/Test2/about.html',
controller: 'about',
requireADLogin: true
})
.otherwise({
redirectTo: '/home'
})
//$locationProvider.html5Mode(true).hashPrefix('!');
}]);
app.config(['$httpProvider', 'adalAuthenticationServiceProvider',
function ($httpProvider, adalAuthenticationServiceProvider) {
// endpoint to resource mapping(optional)
var endpoints = {
"https://localhost/Api/": "xxx-bae6-4760-b434-xxx",
};
adalAuthenticationServiceProvider.init(
{
// Config to specify endpoints and similar for your app
clientId: "xxx-b7ab-4d1c-8cc8-xxx", // Required
//localLoginUrl: "/login", // optional
//redirectUri : "your site", optional
extraQueryParameter: 'domain_hint=mydomain.com',
endpoints: endpoints // If you need to send CORS api requests.
},
$httpProvider // pass http provider to inject request interceptor to attach tokens
);
}]);
})();调用端点的角码:
$scope.getItems = function () {
$http.get("https://localhost/Api/Items")
.then(function (response) {
$scope.items = response.Items;
});发布于 2017-06-29 21:15:26
好吧,我一直把头撞在墙上想办法解决这个问题。试图使我的ADAL.js SPA应用程序(sans角)成功地提出跨域XHR请求到我宝贵的CORS支持的Web。
所有像我这样的新手使用的这个示例应用程序都有这样的问题:它的特点是API和SPA都来自同一个域,并且只需要注册一个AD租户应用程序。这只会让事情变得混乱,当需要把东西分开分开的时候。
所以,开箱即用,这个样本有一个Startup.Auth.cs,它可以正常工作,就这个示例来说……
public void ConfigureAuth(IAppBuilder app) {
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
Audience = ConfigurationManager.AppSettings["ida:Audience"],
Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
});
}但是,您需要修改上面的代码,删除Audience赋值,然后选择一个受众数组。没错:ValidAudiences ..。因此,对于与您的WebAPI通信的每个SPA客户端,您都希望将SPA注册的ClientID放在这个数组中.
它应该是这样的.
public void ConfigureAuth(IAppBuilder app)
{
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
TokenValidationParameters = new TokenValidationParameters
{
ValidAudiences = new [] {
ConfigurationManager.AppSettings["ida:Audience"],//my swagger SPA needs this 1st one
"b2d89382-f4d9-42b6-978b-fabbc8890276",//SPA ClientID 1
"e5f9a1d8-0b4b-419c-b7d4-fc5df096d721" //SPA ClientID 2
},
RoleClaimType = "roles" //Req'd only if you're doing RBAC
//i.e. web api manifest has "appRoles"
}
});
}编辑
好的,基于@JonathanRupp的反馈,我能够反转我使用的Web解决方案,并且能够修改我的客户端JavaScript,如下所示,使一切正常工作。
// Acquire Token for Backend
authContext.acquireToken("https://mycorp.net/WebApi.MyCorp.RsrcID_01", function (error, token) {
// Handle ADAL Error
if (error || !token) {
printErrorMessage('ADAL Error Occurred: ' + error);
return;
}
// Get TodoList Data
$.ajax({
type: "GET",
crossDomain: true,
headers: {
'Authorization': 'Bearer ' + token
},
url: "https://api.mycorp.net/odata/ToDoItems",
}).done(function (data) {
// For Each Todo Item Returned, do something
var output = data.value.reduce(function (rows, todoItem, index, todos) {
//omitted
}, '');
// Update the UI
//omitted
}).fail(function () {
//do something with error
}).always(function () {
//final UI cleanup
});
});发布于 2016-02-25 13:32:33
您需要让您的Web知道您的客户端应用程序。仅从客户端向API添加委托权限是不够的。
要让API客户端知道,请转到Azure管理门户,下载API的清单并将客户端应用程序的ClientID添加到"knownClientApplications“列表中。
要允许隐式流,还需要在清单中将"oauth2AllowImplicitFlow“设置为true。
将清单上载回API应用程序。
发布于 2016-12-29 05:04:47
ADAL.js在调用运行在不同域上的Azure保护API时,确实将access_token与id_token区别开来。最初,在登录期间,它只需使用id_token。此令牌有权访问同一域的资源。但是,在调用运行在不同域中的API时,adal拦截器会检查API是否配置在adal.init()中的端点中。
只有到那时,才会为请求的资源调用访问令牌。它还要求SPA在AAD中配置为访问API应用程序。
实现这一目标的关键是: 1.在adal.init()中添加端点
var endpoints = {
// Map the location of a request to an API to a the identifier of the associated resource
//"Enter the root location of your API app here, e.g. https://contosotogo.azurewebsites.net/":
// "Enter the App ID URI of your API app here, e.g. https://contoso.onmicrosoft.com/TestAPI",
"https://api.powerbi.com": "https://analysis.windows.net/powerbi/api",
"https://localhost:44300/": "https://testpowerbirm.onmicrosoft.com/PowerBICustomServiceAPIApp"
};
adalProvider.init(
{
instance: 'https://login.microsoftonline.com/',
tenant: 'common',
clientId: '2313d50b-7ce9-4c0e-a142-ce751a295175',
extraQueryParameter: 'nux=1',
endpoints: endpoints,
requireADLogin: true,
//cacheLocation: 'localStorage', // enable this for IE, as sessionStorage does not work for localhost.
// Also, token acquisition for the To Go API will fail in IE when running on localhost, due to IE security restrictions.
},
$httpProvider
);
有关详细信息,请参阅此链接:ADAL.js深潜
https://stackoverflow.com/questions/32352325
复制相似问题