我已经尝试了一些 angular-adal 库,但 token 的更新不是自动完成的。
这是我使用的配置。
在 package.json 中
"@types/adal": "^1.0.29",
"@types/adal-angular": "^1.0.0",
"adal-angular": "^1.0.17",
adal-angular 带有两个脚本 adal.js
和 adal-angular.js
。我认为 adal.angular.js
仅适用于旧的 angularjs
解决方案。所以我使用了 adal.js 和包装器@types/adal。
并在 .angular-cli.json
中包含 adal.js
"scripts": [
"../node_modules/adal-angular/lib/adal.js"
],
在我的 angular 5 应用程序中,我使用 adal 登录并向另一个 url 上的网站发出请求 api 请求。
使用的配置
JwtConfig: {
tenant: "a1d50521-9687-4e4d-a76d-xxxxxxxxx",
clientId: "8d708afe-2966-40b7-918c-xxxxxxxx",
isAngular: true
},
我的 authService 看起来像
import { } from "adal";
@Injectable()
export class AuthService {
private _config: adal.Config;
private _context: adal.AuthenticationContext;
constructor() {
Logging = {
level: 3,
log: function (message) {
console.log(message);
}
};
this._config = environment.JwtConfig;
this._context = new AuthenticationContext(this._config);
}
不需要日志记录但启用 adal.js 日志记录
很多示例将 token 存储在本地存储中,但此 token 仅在 1 小时内有效。为了解决这个问题,我每次都调用 acquireToken。它会给我缓存的 token ,如果它过期了,它会给我更新。
acquireToken(): Observable<string> {
return new Observable<string>((subscriber: Subscriber<string>) => {
if (window.frameElement && window.frameElement.id === "adalIdTokenFrame")
subscriber.next(null);
else {
const user = this._context.getCachedUser();
return this._context.acquireToken(environment.JwtConfig.clientId, (message: string, token: string) => {
subscriber.next(token);
});
}
});
}
要让它正常工作,有许多棘手的事情。
更新是在向 Microsoft AD 发出请求的隐藏 I 框架中完成的
https://login.microsoftonline.com/xxxtenantIDxxx/oauth2/authorize?response_type=id_token&client_id=xxx-xx-x-xx
响应将重定向到 http://localhost:4200/...
,这将启动此隐藏 IFrame 中的另一个 Angular 应用程序
此检查 if (window.frameElement && window.frameElement.id === "adalIdTokenFrame")
将防止隐藏 IFrame 的无限循环。
const user = this._context.getCachedUser();
行是必需的,以便 adal 知道有一个用户并将更新该用户,而不是一条用户必须登录的消息。
这似乎工作正常。如果 token 已过期 New Date(profile.exp*1000)
几个小时。用户仍然可以续订此 token 。
有没有办法防止我的 Angular 应用程序加载到隐藏的 Iframe 中?使用有效的包装器或其他一些技巧?
最佳答案
添加脚本以防止在隐藏框架中加载 Angular 。这使得 token 的登录/更新更快。当第一次在浏览器中加载时,它可以防止 angular 启动树次。
此脚本可以添加到 index.html 中。它检查它是否加载到隐藏框架中,解码 token 并防止加载 Angular 。
<script>
if (window.parent && window.parent.AuthenticationContext) {
var self = window.parent._adalInstance;
var hash = window.location.hash;
if (self.isCallback(hash)) {
self.info("Returned from redirect url");
var requestInfo = self.getRequestInfo(hash);
var tokenReceivedCallback = self._callBackMappedToRenewStates[requestInfo.stateResponse];
self.saveTokenFromHash(requestInfo);
var token = requestInfo.parameters[self.CONSTANTS.ACCESS_TOKEN] || requestInfo.parameters[self.CONSTANTS.ID_TOKEN];
var tokenType = self.CONSTANTS.ACCESS_TOKEN;
var errorDesc = requestInfo.parameters[self.CONSTANTS.ERROR_DESCRIPTION];
var error = requestInfo.parameters[self.CONSTANTS.ERROR];
try {
if (tokenReceivedCallback)
tokenReceivedCallback(errorDesc, token, error, tokenType);
} catch (err) {
self.error("Error occurred in user defined callback function: " + err);
}
document.write('<style type="text/undefined">');
}
}
</script>
更新: 使用 Adal en MSAL,您可以使用弹出窗口,但某些 IE 版本对此有问题。 MSAL 没有 adal 复杂
import * as Msal from 'msal';
export const config: Msal.Configuration {
auth: { clientId: '.....-1796-...'},
cache: { cacheLocation: 'localStorage' },
};
constructor() {
this.adAuthenticationContext = new Msal.UserAgentApplication(config);
}
关于angular 5 adal.js 自动 token 更新负载 Angular 两次或更多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49099740/