I have tried a number of angular-adal libraries but the renew of the token is not automatic done.
This the configuration I used.
In package.json
"@types/adal": "^1.0.29",
"@types/adal-angular": "^1.0.0",
"adal-angular": "^1.0.17",
adal-angular come with two scripts adal.js
and adal-angular.js
. I think adal.angular.js
is only for old angularjs
solutions. So I used adal.js and an wrapper @types/adal.
and include the adal.js
in the .angular-cli.json
"scripts": [
"../node_modules/adal-angular/lib/adal.js"
],
In my angular 5 application I use adal to log on and make request api request to website on another url.
The used config
JwtConfig: {
tenant: "a1d50521-9687-4e4d-a76d-xxxxxxxxx",
clientId: "8d708afe-2966-40b7-918c-xxxxxxxx",
isAngular: true
},
My authService looks like
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);
}
The logging is not needed but enables adal.js logging
A lot of examples store there token in localstorage but this token is only valid for 1 hour. To solve this problem I call acquireToken everytime. It will give me the cached token or a renewed if it is expired.
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);
});
}
});
}
To get this working right there are a number of tricky things.
The renewal is done in a hidden I frame what makes a request to microsoft AD
https://login.microsoftonline.com/xxxtenantIDxxx/oauth2/authorize?response_type=id_token&client_id=xxx-xx-x-xx
the response will redirect to http://localhost:4200/...
that will start another angular application in this hidden IFrame
this check if (window.frameElement && window.frameElement.id === "adalIdTokenFrame")
will prevent an endless loop of hidden IFrames.
The line const user = this._context.getCachedUser();
is needed so that adal knows there is a user and will renew the user instead a message that the user must login.
This seems to work ok. If the token is expired New Date(profile.exp*1000)
for several hours. The user can still renew this token.
Is there a way to prevent that my Angular apllication is loaded in the hidden Iframe? With a working wrapper or some other trick?