ADAL.js - 获取 Graph API 资源的令牌
ADAL.js - acquire token for Graph API resources
我正在 React 中开发一个 SPA 应用程序,它需要与 AzureAD 和 GraphAPI(隐式流)集成。
我的问题与以下内容非常相似:ADAL.js - Obtaining Microsoft Graph Access Token with id_token ...但答案没有显示足够的代码让我继续前进。
到目前为止,仅使用 adal.js (v1.0.14),我可以登录并获得一个 id_token,但我不知道如何使用它来获得制作 Graph 的权限API 调用。
更新:我知道我已正确注册到 Azure 门户,因为我能够在没有 adal.js 或任何库的情况下登录并获取最新文档...只需使用自制的 ajax 来电。
这是我的代码,它执行 login/redirect,然后尝试获取我最近的文档:
// Initial setup
var adalCfg = {
instance : 'https://login.microsoftonline.com/',
tenant : 'common',
clientId : 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
postLogoutRedirectUri : window.location.origin,
extraQueryParameter : 'scope=Mail.ReadWrite+Files.Read+Files.ReadWrite+User.ReadBasic.All' // Is this the proper way to specify what resources I need access to?
};
var authContext = new Adal(adalCfg);
if(!authContext.getCachedUser()) {
authContext.login(); // redirects MS login page successfully
}
// Check For & Handle Redirect From AAD After Login
var isCallback = authContext.isCallback(window.location.hash); // Checks if the URL fragment contains access token, id token or error_description.
if(isCallback) {
authContext.handleWindowCallback(); // extracts the hash, processes the token or error, saves it in the cache and calls the registered callbacks with the result.
}
if (isCallback && !authContext.getLoginError()) {
window.location = authContext._getItem(authContext.CONSTANTS.STORAGE.LOGIN_REQUEST); // redirects back to /
}
// Try to get my recent docs - FAILS with InvalidAuthenticationToken error
// UDPATED authContext.acquireToken(authContext.config.clientId, function (error, token) {
authContext.acquireToken('https://graph.microsoft.com', function (error, token) {
$.ajax({
url: 'https://graph.microsoft.com/v1.0/me/drive/recent',
headers:{'authorization':'Bearer '+ token},
type:'GET',
dataType:'json'
}).done(function(res) {
console.log(res['value']);
});
});
我错了什么?
更新 2:我根据 Fei 的回答更改了 acquireToken
,但是现在当 adal 静默获取我的资源的访问令牌时,它无法将其传递给我的 API 调用。
更新代码:
adalCfg.endpoints.graphApiUri = "https://graph.microsoft.com";
authContext.acquireToken(adalCfg.endpoints.graphApiUri, function (errorDesc, token, error) {
console.log('errorDesc = ' + errorDesc)
console.log('token = ' + token)
console.log('error = ' + error)
$.ajax({
url: adalCfg.endpoints.graphApiUri + '/v1.0/me/drive/recent',
headers:{'authorization':'Bearer '+ token},
type:'GET',
dataType:'json'
}).done(function(res) {
console.log(res['value']);
});
});
控制台输出:
Token not being captured
图像显示了对令牌的请求,它似乎成功了,因为下一个 GET 包含散列中的 access_token
。但是,acquireToken
将 null
令牌传递给我的 Graph API 调用。
但是,如果我手动从哈希中获取访问令牌,我可以成功地调用 Graph API。
为什么 adal 不将访问令牌传递给我的 API 调用?它回来了并且有效。
要调用 Microsoft Graph,我们需要获取此资源的特定令牌。根据您使用 authContext.config.clientId
获取令牌的代码。
如果您在 Azure 门户上注册应用程序,要获取 Microsoft Graph 的访问令牌,您需要将 authContext.config.clientId
替换为 https://graph.microsoft.com
。
要成功调用REST,我们需要确保有足够的权限。例如,要列出最近的文件,需要以下范围之一:Files.Read
、Files.ReadWrite
、Files.Read.All
、Files.ReadWrite.All
、Sites.Read.All
、Sites.ReadWrite.All
(参考here)。
更新
<html>
<head>
<script src="\node_modules\jquery\dist\jquery.js"></script>
<script src="node_modules\adal-angular\lib\adal.js"></script>
</head>
<body>
<button id="login"> login</button>
<button id="clickMe">click me</button>
<script>
$(function () {
var endpoints = {
"https://graph.microsoft.com": "https://graph.microsoft.com"
};
window.config = {
tenant: 'xxxx.onmicrosoft.com',
clientId: 'xxxxxxxxxxxxxxxxx',
endpoints: endpoints
};
window.authContext = new AuthenticationContext(config);
$("#login").click(function () {
window.authContext.login();
});
$("#clickMe").click(function () {
var user = window.authContext.getCachedUser();
console.log(user);
window.authContext.acquireToken('https://graph.microsoft.com', function (error, token) {
console.log(error);
console.log(token);
$.ajax({
url: 'https://graph.microsoft.com/v1.0/me/',
headers:{'authorization':'Bearer '+ token},
type:'GET',
dataType:'json'
}).done(function(res) {
console.log(res['userPrincipalName']);
});
});
}
);
function init(){
if(window.location.hash!="")
window.authContext.handleWindowCallback(window.location.hash);
}
init();
});
</script>
</body>
</html>
我正在 React 中开发一个 SPA 应用程序,它需要与 AzureAD 和 GraphAPI(隐式流)集成。
我的问题与以下内容非常相似:ADAL.js - Obtaining Microsoft Graph Access Token with id_token ...但答案没有显示足够的代码让我继续前进。
到目前为止,仅使用 adal.js (v1.0.14),我可以登录并获得一个 id_token,但我不知道如何使用它来获得制作 Graph 的权限API 调用。
更新:我知道我已正确注册到 Azure 门户,因为我能够在没有 adal.js 或任何库的情况下登录并获取最新文档...只需使用自制的 ajax 来电。
这是我的代码,它执行 login/redirect,然后尝试获取我最近的文档:
// Initial setup
var adalCfg = {
instance : 'https://login.microsoftonline.com/',
tenant : 'common',
clientId : 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
postLogoutRedirectUri : window.location.origin,
extraQueryParameter : 'scope=Mail.ReadWrite+Files.Read+Files.ReadWrite+User.ReadBasic.All' // Is this the proper way to specify what resources I need access to?
};
var authContext = new Adal(adalCfg);
if(!authContext.getCachedUser()) {
authContext.login(); // redirects MS login page successfully
}
// Check For & Handle Redirect From AAD After Login
var isCallback = authContext.isCallback(window.location.hash); // Checks if the URL fragment contains access token, id token or error_description.
if(isCallback) {
authContext.handleWindowCallback(); // extracts the hash, processes the token or error, saves it in the cache and calls the registered callbacks with the result.
}
if (isCallback && !authContext.getLoginError()) {
window.location = authContext._getItem(authContext.CONSTANTS.STORAGE.LOGIN_REQUEST); // redirects back to /
}
// Try to get my recent docs - FAILS with InvalidAuthenticationToken error
// UDPATED authContext.acquireToken(authContext.config.clientId, function (error, token) {
authContext.acquireToken('https://graph.microsoft.com', function (error, token) {
$.ajax({
url: 'https://graph.microsoft.com/v1.0/me/drive/recent',
headers:{'authorization':'Bearer '+ token},
type:'GET',
dataType:'json'
}).done(function(res) {
console.log(res['value']);
});
});
我错了什么?
更新 2:我根据 Fei 的回答更改了 acquireToken
,但是现在当 adal 静默获取我的资源的访问令牌时,它无法将其传递给我的 API 调用。
更新代码:
adalCfg.endpoints.graphApiUri = "https://graph.microsoft.com";
authContext.acquireToken(adalCfg.endpoints.graphApiUri, function (errorDesc, token, error) {
console.log('errorDesc = ' + errorDesc)
console.log('token = ' + token)
console.log('error = ' + error)
$.ajax({
url: adalCfg.endpoints.graphApiUri + '/v1.0/me/drive/recent',
headers:{'authorization':'Bearer '+ token},
type:'GET',
dataType:'json'
}).done(function(res) {
console.log(res['value']);
});
});
控制台输出:
Token not being captured
图像显示了对令牌的请求,它似乎成功了,因为下一个 GET 包含散列中的 access_token
。但是,acquireToken
将 null
令牌传递给我的 Graph API 调用。
但是,如果我手动从哈希中获取访问令牌,我可以成功地调用 Graph API。
为什么 adal 不将访问令牌传递给我的 API 调用?它回来了并且有效。
要调用 Microsoft Graph,我们需要获取此资源的特定令牌。根据您使用 authContext.config.clientId
获取令牌的代码。
如果您在 Azure 门户上注册应用程序,要获取 Microsoft Graph 的访问令牌,您需要将 authContext.config.clientId
替换为 https://graph.microsoft.com
。
要成功调用REST,我们需要确保有足够的权限。例如,要列出最近的文件,需要以下范围之一:Files.Read
、Files.ReadWrite
、Files.Read.All
、Files.ReadWrite.All
、Sites.Read.All
、Sites.ReadWrite.All
(参考here)。
更新
<html>
<head>
<script src="\node_modules\jquery\dist\jquery.js"></script>
<script src="node_modules\adal-angular\lib\adal.js"></script>
</head>
<body>
<button id="login"> login</button>
<button id="clickMe">click me</button>
<script>
$(function () {
var endpoints = {
"https://graph.microsoft.com": "https://graph.microsoft.com"
};
window.config = {
tenant: 'xxxx.onmicrosoft.com',
clientId: 'xxxxxxxxxxxxxxxxx',
endpoints: endpoints
};
window.authContext = new AuthenticationContext(config);
$("#login").click(function () {
window.authContext.login();
});
$("#clickMe").click(function () {
var user = window.authContext.getCachedUser();
console.log(user);
window.authContext.acquireToken('https://graph.microsoft.com', function (error, token) {
console.log(error);
console.log(token);
$.ajax({
url: 'https://graph.microsoft.com/v1.0/me/',
headers:{'authorization':'Bearer '+ token},
type:'GET',
dataType:'json'
}).done(function(res) {
console.log(res['userPrincipalName']);
});
});
}
);
function init(){
if(window.location.hash!="")
window.authContext.handleWindowCallback(window.location.hash);
}
init();
});
</script>
</body>
</html>