ADAL JS 在调用 WebAPI 时不附加用户令牌
ADAL JS not attaching user token while invoking WebApi
我正在使用ADAL JS
针对Azure AD对用户进行身份验证。由于我是ADAL JS
新手,我开始阅读以下文章,我觉得这些信息非常丰富:
- 介绍 ADAL JS v1
- ADAL JavaScript 和 AngularJS – Deep Dive
阅读文章后,我的印象是ADAL JS
拦截服务调用,如果服务 url 注册为AuthenticationContext
配置中的终结点之一,它会将 JWT 令牌附加为身份验证持有者信息。
但是,我发现在我的案例中并没有发生同样的情况。经过一番挖掘,在我看来,只有在同时使用adal-angular
对应部分的情况下才有可能,而我目前没有使用,仅仅是因为我的 Web 应用程序不是基于 Angular。
请让我知道我的理解是否正确。如果我需要显式添加持有者信息,也可以这样做,但我更关心我是否缺少一些开箱即用的功能。
其他详细信息:我目前的配置如下所示:
private endpoints: any = {
"https://myhost/api": "here_goes_client_id"
}
...
private config: any;
private authContext: any = undefined;
....
this.config = {
tenant: "my_tenant.onmicrosoft.com",
clientId: "client_id_of_app_in_tenant_ad",
postLogoutRedirectUri: window.location.origin,
cacheLocation: "sessionStorage",
endpoints: this.endpoints
};
this.authContext = new (window["AuthenticationContext"])(this.config);
同样在服务器端(WebApi),身份验证配置(Startup.Auth)如下所示:
public void ConfigureOAuth(IAppBuilder app, HttpConfiguration httpConfig)
{
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
Tenant = "my_tenant.onmicrosoft.com",
TokenValidationParameters = new TokenValidationParameters
{
ValidAudience = "client_id_of_app_in_tenant_ad"
}
});
}
但是,Authorization
在 request.Headers
中始终为空。
更新:似乎这同样适用于代币的自动续订; 当与adal-angular
结合使用时,令牌的续订通过在引擎盖下调用AuthenticationContext.acquireToken(resource, callback)
无缝工作。如果我错了,请纠正我。
阅读文章后,我的印象是 ADAL JS 会拦截服务调用,如果服务 URL 在 AuthenticationContext 配置中注册为终结点之一,它会将 JWT 令牌附加为身份验证持有者信息。
仅当您的应用程序是基于角度的时,这才有效。正如你提到的,这个逻辑存在于adal-angular中。
但是,如果你想坚持使用纯JS,你将无法获得自动的"get-access-token-and-attach-it-to-header"支持。可以使用acquireToken(resource, callback
API 获取终结点的令牌。但是,您必须在将请求发送到 API 的控制器中执行一些工作。
这可能会给你一些想法:https://github.com/Azure-Samples/active-directory-javascript-singlepageapp-dotnet-webapi/blob/master/TodoSPA/App/Scripts/Ctrls/todoListCtrl.js。此示例不使用角度。
ADAL.JS 与 v2.0 隐式流不兼容。我无法让它工作,因为我最近设置了我的项目,并且不认为项目是向后兼容的。
这非常令人困惑,花了很长时间才弄清楚我混淆了版本,并且不能将 ADAL.JS 与 v2.0 一起使用。一旦我删除它,事情就顺利多了,只是做了几个 XHR 请求和一个弹出窗口,实际上不需要魔法!
下面是 v2 的代码:
function testNoADAL() {
var clientId = "..guid..";
var redirectUrl = "..your one.."
var authServer = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?";
var responseType = "token";
var stateParam = Math.random() * new Date().getTime();
var authUrl = authServer +
"response_type=" + encodeURI(responseType) +
"&client_id=" + encodeURI(clientId) +
"&scope=" + encodeURI("https://outlook.office.com/Mail.ReadWrite") +
"&redirect_uri=" + encodeURI(redirectUrl) +
"&state=" + stateParam;
var popupWindow = window.open(authUrl, "Login", 'width=' + 300 + ', height=' + 600 + ', top=' + 10 + ', left=' + 10 + ',location=no,toolbar=yes');
if (popupWindow.focus) {
popupWindow.focus();
}
}
注意:重定向URL会出现在弹出窗口中,需要有代码才能传递位置哈希,例如:
<script>window.opener.processMicrosoftAuthResultUrl(location.hash);window.close();</script>
function processMicrosoftAuthResultUrl(hash) {
if (hash.indexOf("#") == 0) {
hash = hash.substr(1);
}
var obj = getUrlParameters(hash);
if (obj.error) {
if (obj.error == "invalid_resource") {
errorDialog("Your Office 365 needs to be configured to enable access to Outlook Mail.");
} else {
errorDialog("ADAL: " + obj.error_description);
}
} else {
if (obj.access_token) {
console.log("ADAL got access token!");
var token = obj.access_token;
var url = "https://outlook.office.com/api/v2.0/me/MailFolders/Inbox/messages";
$.ajax({
type: "GET",
url: url,
headers: {
'Authorization': 'Bearer ' + token,
},
}).done(function (data) {
console.log("got data!", data);
var message = "Your latest email is: " + data.value[0].Subject + " from " + data.value[0].From.EmailAddress.Name+ " on " + df_FmtDateTime(new Date(data.value[0].ReceivedDateTime));
alertDialog(message);
}).fail(function () {
console.error('Error getting todo list data')
});
}
}
}
function getUrlParameters(url) {
// get querystring and turn it into an object
if (!url) return {};
if (url.indexOf("?") > -1) {
url = url.split("?")[1];
}
if (url.indexOf("#") > -1) {
url = url.split("#")[0];
}
if (!url) return {};
url = url.split('&')
var b = {};
for (var i = 0; i < url.length; ++i) {
var p = url[i].split('=', 2);
if (p.length == 1) {
b[p[0]] = "";
} else {
b[decodeURIComponent(p[0])] = decodeURIComponent(p[1].replace(/'+/g, " "));
}
}
return b;
}
- 如何获取登录用户的twitter oAuth令牌
- 在每个 AJAX 请求(Sencha Touch 2)中发送用户详细信息(会话令牌)
- 打开图形:Java脚本:必须使用活动访问令牌来查询有关当前用户的信息
- 通过oauth令牌passport.js访问用户配置文件
- 必须使用活动访问令牌来查询有关具有打开图的当前用户的信息
- 谷歌'的用户令牌和授权代码
- AngularJS如何解码带有令牌和内部用户信息的jsonp响应
- 在JS web应用程序中,如何确保具有访问令牌的恶意用户无法刷新它
- 如何获取用户访问令牌,与图形 API 资源管理器中使用的令牌相同
- 仅使用访问令牌在节点中获取Google+用户配置文件
- ADAL JS 在调用 WebAPI 时不附加用户令牌
- 条带用户令牌问题
- 使用具有应用程序访问令牌的图形 API 搜索用户
- 从用户电子邮件创建哈希/令牌以进行电子邮件验证
- 当用户不想被记住时存储令牌的位置
- FB.logout() - 无访问令牌 - “以其他用户身份登录”
- FB PHP SDK 的 getAccessToken() 是检索用户身份验证令牌的可靠方法吗?
- 如果用户喜欢Facebook页面,则无需请求访问令牌
- 如何在会话令牌过期时将用户重定向到登录页面
- 如何在每个JsonP请求中发送用户令牌