ADAL.js:令牌过期后如何强制用户重新输入密码
ADAL.js: How to force user to re-enter password after token expiry
我有一个使用 adal-angular (https://github.com/AzureAD/azure-activedirectory-library-for-js) 进行安全访问的单页应用程序。
每当令牌过期时(1 小时后),我想将用户重定向到 AD 登录屏幕,重新输入他们的密码。
我修改了 adal-angular.js 以在令牌过期时调用 _adal.login() ,但这似乎会自动重新验证用户并将他们直接带到带有更新令牌的重定向 URI。
我不确定缓存的是什么,允许自动续订。
如何在令牌过期时强制用户重新输入密码?
AFAIK,当令牌过期时,adal.js 使用 iframe 中的隐式流获取令牌。不支持强制用户重新登录
要实现此功能,您可以修改源代码。下面是修改adal.js中的acquireToken
和login
方法的代码示例,供大家参考:
AuthenticationContext.prototype.acquireToken = function (resource, callback) {
if (this._isEmpty(resource)) {
this.warn('resource is required');
callback('resource is required', null, 'resource is required');
return;
}
var token = this.getCachedToken(resource);
if (token) {
this.info('Token is already in cache for resource:' + resource);
callback(null, token, null);
return;
}
//add by me-begin
var expiry = this._getItem(this.CONSTANTS.STORAGE.EXPIRATION_KEY + resource);
var isExpired = true;
// If expiration is within offset, it will force renew
var offset = this.config.expireOffsetSeconds || 300;
if (expiry && (expiry > this._now() + offset)) {
isExpired = false;
}
//add by me-end
if (!this._user) {
this.warn('User login is required');
callback('User login is required', null, 'login required');
return;
}
//add by me-begin
else if (isExpired) {
this.login(null,"prompt=login");
}
//add by me-end
// refresh attept with iframe
//Already renewing for this resource, callback when we get the token.
if (this._activeRenewals[resource]) {
//Active renewals contains the state for each renewal.
this.registerCallback(this._activeRenewals[resource], resource, callback);
}
else {
if (resource === this.config.clientId) {
// App uses idtoken to send to api endpoints
// Default resource is tracked as clientid to store this token
this.verbose('renewing idtoken');
this._renewIdToken(callback);
} else {
this._renewToken(resource, callback);
}
}
};
//add the extraParameters to force user sign-in
AuthenticationContext.prototype.login = function (loginStartPage,extraParameters) {
// Token is not present and user needs to login
if (this._loginInProgress) {
this.info("Login in progress");
return;
}
var expectedState = this._guid();
this.config.state = expectedState;
this._idTokenNonce = this._guid();
this.verbose('Expected state: ' + expectedState + ' startPage:' + window.location.href);
this._saveItem(this.CONSTANTS.STORAGE.LOGIN_REQUEST, loginStartPage || window.location.href);
this._saveItem(this.CONSTANTS.STORAGE.LOGIN_ERROR, '');
this._saveItem(this.CONSTANTS.STORAGE.STATE_LOGIN, expectedState);
this._saveItem(this.CONSTANTS.STORAGE.NONCE_IDTOKEN, this._idTokenNonce);
this._saveItem(this.CONSTANTS.STORAGE.ERROR, '');
this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, '');
var urlNavigate = this._getNavigateUrl('id_token', null) + '&nonce=' + encodeURIComponent(this._idTokenNonce);
urlNavigate = urlNavigate + "&"+extraParameters;//add by me
this._loginInProgress = true;
if (this.config.displayCall) {
// User defined way of handling the navigation
this.config.displayCall(urlNavigate);
}
else if (this.popUp) {
this._loginPopup(urlNavigate);
}
else {
this.promptUser(urlNavigate);
}
};
如果您对此库有任何想法或反馈,可以从 here 提出一个新问题。
我有一个使用 adal-angular (https://github.com/AzureAD/azure-activedirectory-library-for-js) 进行安全访问的单页应用程序。 每当令牌过期时(1 小时后),我想将用户重定向到 AD 登录屏幕,重新输入他们的密码。 我修改了 adal-angular.js 以在令牌过期时调用 _adal.login() ,但这似乎会自动重新验证用户并将他们直接带到带有更新令牌的重定向 URI。 我不确定缓存的是什么,允许自动续订。
如何在令牌过期时强制用户重新输入密码?
AFAIK,当令牌过期时,adal.js 使用 iframe 中的隐式流获取令牌。不支持强制用户重新登录
要实现此功能,您可以修改源代码。下面是修改adal.js中的acquireToken
和login
方法的代码示例,供大家参考:
AuthenticationContext.prototype.acquireToken = function (resource, callback) {
if (this._isEmpty(resource)) {
this.warn('resource is required');
callback('resource is required', null, 'resource is required');
return;
}
var token = this.getCachedToken(resource);
if (token) {
this.info('Token is already in cache for resource:' + resource);
callback(null, token, null);
return;
}
//add by me-begin
var expiry = this._getItem(this.CONSTANTS.STORAGE.EXPIRATION_KEY + resource);
var isExpired = true;
// If expiration is within offset, it will force renew
var offset = this.config.expireOffsetSeconds || 300;
if (expiry && (expiry > this._now() + offset)) {
isExpired = false;
}
//add by me-end
if (!this._user) {
this.warn('User login is required');
callback('User login is required', null, 'login required');
return;
}
//add by me-begin
else if (isExpired) {
this.login(null,"prompt=login");
}
//add by me-end
// refresh attept with iframe
//Already renewing for this resource, callback when we get the token.
if (this._activeRenewals[resource]) {
//Active renewals contains the state for each renewal.
this.registerCallback(this._activeRenewals[resource], resource, callback);
}
else {
if (resource === this.config.clientId) {
// App uses idtoken to send to api endpoints
// Default resource is tracked as clientid to store this token
this.verbose('renewing idtoken');
this._renewIdToken(callback);
} else {
this._renewToken(resource, callback);
}
}
};
//add the extraParameters to force user sign-in
AuthenticationContext.prototype.login = function (loginStartPage,extraParameters) {
// Token is not present and user needs to login
if (this._loginInProgress) {
this.info("Login in progress");
return;
}
var expectedState = this._guid();
this.config.state = expectedState;
this._idTokenNonce = this._guid();
this.verbose('Expected state: ' + expectedState + ' startPage:' + window.location.href);
this._saveItem(this.CONSTANTS.STORAGE.LOGIN_REQUEST, loginStartPage || window.location.href);
this._saveItem(this.CONSTANTS.STORAGE.LOGIN_ERROR, '');
this._saveItem(this.CONSTANTS.STORAGE.STATE_LOGIN, expectedState);
this._saveItem(this.CONSTANTS.STORAGE.NONCE_IDTOKEN, this._idTokenNonce);
this._saveItem(this.CONSTANTS.STORAGE.ERROR, '');
this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, '');
var urlNavigate = this._getNavigateUrl('id_token', null) + '&nonce=' + encodeURIComponent(this._idTokenNonce);
urlNavigate = urlNavigate + "&"+extraParameters;//add by me
this._loginInProgress = true;
if (this.config.displayCall) {
// User defined way of handling the navigation
this.config.displayCall(urlNavigate);
}
else if (this.popUp) {
this._loginPopup(urlNavigate);
}
else {
this.promptUser(urlNavigate);
}
};
如果您对此库有任何想法或反馈,可以从 here 提出一个新问题。