grumar / adal-angular5 Goto Github PK
View Code? Open in Web Editor NEWThis project forked from benbaran/adal-angular4
Angular 5 ADAL Wrapper
License: MIT License
This project forked from benbaran/adal-angular4
Angular 5 ADAL Wrapper
License: MIT License
The Adal5Interceptor always uses the user token for the bearer token. This is not consistent with the ADAL library that maintains a token per resource and uses the appropriate token. this functionality existed in the original library this was forked from:
export class AdalInterceptor implements HttpInterceptor {
constructor(private adal: AdalService) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// if the endpoint is not registered then pass
// the request as it is to the next handler
const resource = this.adal.GetResourceForEndpoint(req.url);
if (!resource) {
return next.handle(req.clone());
}
// if the user is not authenticated then drop the request
if (!this.adal.userInfo.authenticated) {
throw new Error('Cannot send request to registered endpoint if the user is not authenticated.');
}
// if the endpoint is registered then acquire and inject token
let headers = req.headers || new HttpHeaders();
return this.adal.acquireToken(resource).pipe(
mergeMap((token: string) => {
// inject the header
headers = headers.append('Authorization', 'Bearer ' + token);
return next.handle(req.clone({ headers: headers }));
}
)
)
}
}
has become:
export class Adal5Interceptor implements HttpInterceptor {
constructor(public adal5Service: Adal5Service) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${this.adal5Service.userInfo.token}`
}
});
return next.handle(request);
}
}
Hey there
I've integrated your adal wrapper and found several issues with the Adal5HTTPService.
If the method is omitted, then the request object becomes messed up. The URL is in the method field...
Not sure where the difference comes from, but I'm using Angular 5.1.
Both issues can be fixed by replacing the block in sendRequest method with:
authenticatedCall = this.service.acquireToken(resource)
.flatMap(function (token) {
if (options.headers == null) {
options.headers = new http_1.HttpHeaders();
}
options.headers = options.headers.append('Authorization', 'Bearer ' + token);
return _this.http.request(method, url, options)
.catch(_this.handleError);
});
In package.json there is a reference to angular/http.
I don't see that it is used anywhere.
Since angular/http is deprecated in favor of angular/common/http, the dependency could probably be removed.
I did my adal-angular5 development with Chrome. When I tested with IE11, I started getting an error message: "Error: Incorrect function". My first thought was that a polyfill was needed. Does anyone have a suggestion on this? Thanks.
After upgrading to Angular 6 and rxjs library I started seeing the following.
ERROR in node_modules/@angular/core/src/render3/ng_dev_mode.d.ts(9,11): error TS2451: Cannot redeclare block-scoped variable 'ngDevMode'.
node_modules/adal-angular5/node_modules/@angular/core/src/render3/ng_dev_mode.d.ts(9,11): error TS2451: Cannot redeclare block-scoped variable 'ngDevMode'.
src/app/services/api.service.ts(33,5): error TS2719: Type 'Observable' is not assignable to type 'Observable'. Two different types with this name exist, but they are unrelated.
Property 'operator' is protected in type 'Observable' but public in type 'Observable'.
src/app/services/api.service.ts(39,5): error TS2719: Type 'Observable' is not assignable to type 'Observable'. Two different types with this name exist, but they are unrelated.
I am working in a single page application in which i trying to get token from my backend application. I have followed the example on this site https://github.com/benbaran/adal-angular4-example to initialize the authentication. Immediately after the application is authorized I am calling my service to acquire token for my backend application but I receive the error for my service:
[AuthService -> Http]: NullInjectorError: No provider for Http!
In the service I call a method that calls Adal5Service acquireToken method. Is there a way to call the acquire token method without triggering the error ?
I am working in angular version 5.20.
when running project with ng serve no issues found in azure .All user details , authentication and token are found but when running project with ng build --prod issues found . In get authentication and token. pls help to fixed this soon
I have an angular project(version 5.2), and using ADAL service(adal-angular5). After login first time, no error message comes, but when i refresh the browser, the error message comes as =>
Here is my interceptor code:
constructor(private adalService: Adal5Service, private loaderService: LoaderService) { }
addToken(req: HttpRequest<any>, token: string): HttpRequest<any> {
return req.clone({
url: environment.apiUrl + req.url,
headers: req.headers
.set('Content-Type', 'application/json')
.set('Authorization', 'Bearer ' + token)
});
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.adalService.acquireToken(environment.adalConfig.resource).subscribe();
return next.handle(this.addToken(req, this.adalService.userInfo.token))
.finally(() => this.loaderService.display(false));
}
The definition for this.http.request I believe is this.http.request(url,options) but in code currently it tries this.http.request(method,url,options). This throws an error when trying to make request.
Thanks for the package. It's very helpful !
In adal5.service.ts
the handleWindowCallback
does not take into account of what happens when requestInfo
should be from the parent window or popup
Hello,
I have installed adal angular 5, my angular version is 5. I have followed the example from adal angular4, so i have the following config:
**app.module.ts**
imports: [..., HttpModule,] (shouldn't be here HttpClientModule?)
providers: [
{ provide: LocationStrategy, useClass: HashLocationStrategy },
Adal5Service,
{
provide: Adal5HTTPService,
useFactory: Adal5HTTPService.factory,
deps: [Http, Adal5Service] (shouldn't be HttpClient?)
}
]
I can successfully login, using Adal5Service login method.
But when i try to make an http request, using Adal5HTTPService, i am still unauthorized.
What am i doing wrong?
Thank you
Code changes are required like below,
if (this.service.userInfo.authenticated) {
authenticatedCall = this.service.acquireToken(resource)
.flatMap((token: string) => {
if (options.headers == null) {
options.headers = new HttpHeaders();
}
options.headers = options.headers.set('Authorization', Bearer ${token}
);
return this.http.request(method, url, options)
.catch(this.handleError);
});
}
As far as I can see in the code, the "sendRequest" method in adal5-http.service.js envokes acquireToken with a given resource.
I have added endpoints in which I want to use CORS for several resources. The code below for the "sendRequest" method shows that if one of the added endpoints contains the URL it will try to retreive an access_token from the given resource for the endpoint.
Adal5HTTPService.prototype.sendRequest = function (method, url, options) {
var _this = this;
var resource = this.service.GetResourceForEndpoint(url);
var authenticatedCall;
if (resource) {
if (this.service.userInfo.authenticated) {
authenticatedCall = this.service.acquireToken(resource)
.flatMap(function (token) {
if (options.headers == null) {
options.headers = new http_1.HttpHeaders();
}
options.headers = options.headers.append('Authorization', 'Bearer ' + token);
return _this.http.request(method, url, options)
.catch(_this.handleError);
});
}
else {
authenticatedCall = Rx_1.Observable.throw(new Error('User Not Authenticated.'));
}
}
else {
authenticatedCall = this.http.request(method, url, options).catch(this.handleError);
}
return authenticatedCall;
};
If I add the clientId as the resource I get the id_token from the cache and an attached debugger breaks within the flatMap of the acquireToken. It then set the Authorization header as expected and the code works fine but I am not authorized when using the id_token - I need to use the access_token.
If I - on the other hand - sets the resource for my API application instead of the clientId the debugger never breaks within acquireToken which results in the Authorization header never to be set and therefore my call to the API fails.
I can, in the Network tab in Chrome, see that the query for the access_token has gone through and responded with a callback.
This is my config:
const config = {
tenant: 'cloudrunners.dk',
clientId: '18f5edc3-1111-1111-1111-a9e1b239e2cd',
redirectUri: window.location.origin + '/',
resource: 'https://cloudrunners.dk/151f85ba-1111-1111-1111-1111ccca6f9a',
endpoints: {
'https://local.stuff.com/api/': 'https://cloudrunners.dk/151f85ba-1111-1111-1111-1111ccca6f9a'
}
};
What I have done up until now:
1) Set "oauth2AllowImplicitFlow": true
in the manifest
2) Added API and Client applications to permissions
No matter what I do - and I have seen this in adal-angular and adal-angular4 as well - I can't get it to break inside acquireToken when using the resource and not the clientId to get the access_token.
I have upgraded the Angular4 to Angular5 when i have used adal-angular5 its calling ng-init 2 times . I have tried many solution but not resolved .
Please let me know about it .
Thanks
I've been trying to use the library with no success. A working example would be fantastic.
Your app is full of bugs!
I have some filtering parameters passed as URI params ?filterA=xxx&filterB=yyy, which when I copy and paste to new browser tabs gets cleared by adal-angular5. When I disable adal-angular5 thise URI params don't get cleared.
Hi!
After a successfull id_token retreival I'm making a call to aquireToken like this:
this.service.acquireToken("https:///").subscribe((token) => {console.log("Access token:" + token)}, (error) => {console.log("Error" + error);});
I then see an authorize request beeing sent over the network where the state is set to |.
But the state that is saved in the _renewStates property in the adal context has NOT an url-encoded resource.
When I debug "handleWindowCallback" I see that an access_token is received but there are two problems.
The _renewStates in the adal context in the handleWindowCallback is empty, why is that? Even if the _renewStates wasn't empty adal would still not find a match due to that the received state is url-encoded but the state saved when sending the request is NOT url-encoded. Am I doing something wrong? Please help!
Hi!
Angular 5.2.8 has been released
https://github.com/angular/angular/blob/master/CHANGELOG.md
The library doesn’t work anymore, it’s unable to read the token from hash.
Angular team has updated special chars management in the URI, maybe it causes the issue?
What can we do instead of keeping angular 5.2.7 or lower?
Thank you so much!
Sorry to ask a noob question - but how do I use the latest 2.1.1 version? I need to perform an acquiretoken call which doesn't seem to work in the current version but I think is fixed in version 2.1.1
Hi,
I am also facing some issue with v2.1.1.
1.The app loads 2-3 times. After that I see two errors in console
ERROR TypeError: Cannot read property '4730d8bd-c126-49b3-9714-e7c2c3f56b09|427757c9-9aeb-488c-b149-db1d54c2c3c4' of undefined
at Adal5Service.push../node_modules/adal-angular5/esm5/adal-angular5.js.Adal5Service.handleWindowCallback (adal-angular5.js:77)
ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'access_token'
Error: Cannot match any routes. URL Segment: 'access_token'.
Now if I reload the page, the erros are gone.
4. I am using a version 2.1.1. In node_modules\adal-angular5\esm5\adal-angular5.js the Observable is imported as "import { Observable as Observable$1 } from 'rxjs/Rx';" but in function below 'Observable ' is used instead of 'Observable$1) which is throwing error.
how to update new token when generated token has expired?
Please help me with Adal5Service.acquireToken method. I my case it is always falls with "Token renewal operation failed due to timeout".
Here is app.component.ts:
import { Component, OnInit } from '@angular/core';
import { Adal5Service } from 'adal-angular5';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
constructor(private adalSvc: Adal5Service) {
let config: adal.Config = {
tenant: 'XXX.onmicrosoft.com',
clientId: '21efffd5-29fc-XXX',
postLogoutRedirectUri: window.location.origin,
endpoints: {
graphApiUri: "https://graph.microsoft.com",
},
cacheLocation: "localStorage",
redirectUri: ''
};
this.adalSvc.init(config);
}
ngOnInit(): void {
this.adalSvc.handleWindowCallback();
if (!this.adalSvc.userInfo.authenticated) {
this.adalSvc.login();
return;
}
// work correct
console.log(this.adalSvc.userInfo.username);
this.adalSvc.acquireToken("https://graph.microsoft.com")
.subscribe(
token => console.log(token), // never comes
error => console.log(error)); // error: Token renewal operation failed due to timeout
}
}
I have changed the providers in app.module to HttpClient, and imported HttpClientModule.
But when i want to make a get request, i am asked to provide 2 params: url and options. In the adal angular4, options parameter is optional.
I can't provide an empty dict (can't compile with empty options), and if i change in your source code the options parameter to be optional for get method, i get this error
Cannot read property 'toLowerCase' of undefined
at HttpXsrfInterceptor.intercept (http.js:2482)
How should i do it?
My angular version is 5.0, and angular-cli: 1.6.3.
It appears that i'm not the only one who struggles with this library, perhaps you could provide us an example.
Thank you
adal-angular.d.ts needs to be refactored for compatibility with TypeScript 2.6+ due to a breaking change.
package.json specifies "typescript": "^2.4.2"
Here's an example of refactoring for TypeScript 2.6+ support.
Hi,
I'm trying to use adal-angular5 to handle authentication for my application with azure AD.
My routeGuard works fine with this logic:
if (this._adal.userInfo.authenticated) {
return true;
}
this_adal.login();
return false;
allowing navigation from page to page even after access token expiry, but any AJAX requests are failing with 401 unauthorized, how do I force the re-authentication logic to renew the access token in the event of an AJAX failure/hide access token expiry completely from the user such that the application can be left unattended for 1 hour and still work?
Any working examples would be greatly appreciated.
Hi,
each time i GET something using class Adal5HttpService the ts compiler refuses to do its job if I don't pass parameter options
:
get(url: string, options: {
body?: any;
headers?: HttpHeaders;
reportProgress?: boolean;
observe: 'response';
params?: HttpParams | { [param: string]: string | string[]; };
responseType?: 'json';
withCredentials?: boolean;
})
In the simplest case, where I don't have any option to set, the compiler still refuses to work if I don't set options
to {'observe': 'response'}
I'm new to angular but this seems pretty odd to me, why should i pass a fixed object? wouldn't be possible in case that parameter is omitted to set some default value in Adal5HttpService itself?
edit: could this be fixed by changing the method signature adding an ?
after observe
? or after options
?
thanks in advance
Due to changes in the underlying adal-angular package, adal-angular5 is no longer able to make calls to Microsoft Graph or other services that use the Adal5HTTPService.
I'm using the development release 2.1.1 that successfully addresses some other issues.
Specifically, this line in Adal5Service (adal5.service.ts):
this.adalContext.callback = (window.parent as any).callBackMappedToRenewStates[requestInfo.stateResponse];
now causes an error because callBackMappedToRenewStates was made private (_callBackMappedToRenewStates) in adal-angular as of release 1.0.16.
See this commit:
https://github.com/AzureAD/azure-activedirectory-library-for-js/commits/dev/lib/adal.js
And this issue:
AzureAD/azure-activedirectory-library-for-js#690
Impact:
When I call Microsoft Graph after initial authentication (i.e. after login is called), on the redirect after the access token is retrieved for MS Graph, I get an error in handleWindowCallback because window.parent.callBackMappedToRenewStates is not defined.
Is there no way to call either acquireTokenPopup or acquireTokenRedirect if there is an interaction_required error? My resource is requiring multi-factor authentication, but I can't figure out how to get to it with any of the adal-angular libraries.
If in my Index.cshtml this line of code is present:
<app asp-prerender-module="ClientApp/dist/main-server">Loading...</app>
I get an error:
_NodeInvocationException: window is not defined
ReferenceError: window is not defined
at Adal5Service.init (_
If I move Adal5Service declaration from app.module.server to app.module.browser the error changes to:
_NodeInvocationException: StaticInjectorError(AppModule)[AppComponent -> Adal5Service]:
StaticInjectorError(Platform: core)[AppComponent -> Adal5Service]:
NullInjectorError: No provider for Adal5Service!
Error: StaticInjectorError(AppModule)[AppComponent -> Adal5Service]:
StaticInjectorError(Platform: core)[AppComponent -> Adal5Service]:
NullInjectorError: No provider for Adal5Service!_
But if I replace line
<app asp-prerender-module="ClientApp/dist/main-server">Loading...</app>
with line
<app asp-ng2-prerender-module="ClientApp/dist/main-server">Loading...</app>
in file Index.cshtml - Everything works fine.
Is this an expected behavior or is this an error?
Thank you.
Hello, when I am trying to fetch access Token in my Angular 5 application for the first time after user is logged in, with following method:
adalService.acquireToken(resource)
and I am getting this error:
AuthCallbackComponent_Host.ngfactory.js? [sm]:1 ERROR TypeError: Cannot read property '12345678-abcd-efgh-9876-1fa334df7c72|87654321-asdf-48b2-b9ca-111222333444' of undefined
at Adal5Service.handleWindowCallback (adal-angular5.js:77)
at LoginService.completeAuthentication (login.service.ts:80)
at AuthCallbackComponent.ngOnInit (callback.component.ts:17)
Resource is an API defined on AAD. Login service is my angular service which calls Adal5Service.handleWindowCallback function in this code, during standard, complete authentication, action:
...
public completeAuthentication(): void {
this.adalService.handleWindowCallback();
}
...
Second time Token is received without errors, but I don't want to implement retries. I would rather understand what is going wrong here. Any similar problem faced by anyone?
Thanks a lot. Vedran
The handleWindowCallback refreshing page to remove the hash from url. How can be that fixed?
You can apply this: ollief87@64e81d4
login, accquireToken, handleWindowCallback
Just installed adal-angular 5 in my angular 7 project but when i try to build using ng build it throws me the below error:
ERROR in node_modules/@angular/core/src/render3/ng_dev_mode.d.ts(9,11): error TS2451: Cannot redeclare block-scoped variable 'ngDevMode'.
node_modules/adal-angular5/node_modules/@angular/core/src/render3/ng_dev_mode.d.ts(9,11): error TS2451: Cannot redeclare block-scoped variable 'ngDevMode'.
Any thoughts?
Hello, I am hoping someone can help me to get the Authorization to my Web API working. I've tried every possible source but I can't get a working example. It seems I've ran into similar issue that most people on this page have. It doesn't even seem like it's trying to access the web api. Not getting any errors but it's not returning a response from the Web Api.
I am able to authenticate into the Angular app and receive the token but I am having an issue calling the Web Api. I was able to get it working with the adal-angular4 version so I think the setup in Azure is correct.
I've also tried to upgrade to adal-angular5 version 2.1.1 but then I get this error:
Cannot read property '4717174e-648c-4fb0-872a-e3d6e0bbe5ee|https://adaltestapi.azurewebsites.net' of undefined at Adal5Service.handleWindowCallback
This is my code:
APP.MODULE
providers: [AuthGuardService, AuthService, PlantsService,
Adal5Service, {
provide:Adal5HTTPService,
useFactory:Adal5HTTPService.factory,
deps: [HttpClient, Adal5Service] } ],
AUTHSERVICE
private _config = {
tenant: 'xxxxxx.onmicrosoft.com',
clientId: 'xxxxxx-5a93-46d9-8d41-2a1dbc14c885',
postLogoutRedirectUri: 'https://adaltestapi.azurewebsites.net',
redirectUri:"http://localhost:4400/auth-callback",
endpoints: {
'https://adaltestapi.azurewebsites.net': 'https://adaltestapi.azurewebsites.net'
},
}
constructor(private _adal:Adal5Service) {
this._adal.init(this._config);
}
public startAuthentication():any {
this._adal.login();
}
public completeAuthentication():void {
this._adal.handleWindowCallback();
this._adal.getUser().subscribe(user=> {
this._user=user;
});
PLANTS SERVICE
public getPlants(): Observable<Array> {
const options = this.prepareOptions();
return this.http.get(${environment.apiUrl}
, options)
.map(response => {
const tmp = <IPlant[]>response.json(); --->> NEVER GET THE RESPONSE BACK AND NO REAL ERRORS EITHER
});
}
private prepareOptions():any{
let headers = new HttpHeaders();
headers = headers
.set('Content-Type', 'application/json')
.set('Authorization', Bearer ${this.adal5Service.userInfo.token}
);
return { headers };
}
Any help would be appreciated.
Thanks.
I am working in a single page application in which i trying to get token from my backend application. I have followed the example on this site https://github.com/benbaran/adal-angular4-example to initialize the authentication. Immediately after the application is authorized I am calling my service to acquire token for my backend application but I receive the error for my service:
[AuthService -> Http]: NullInjectorError: No provider for Http!
In the service I call a method that calls Adal5Service acquireToken method. Is there a way to call the acquire token method without triggering the error ?
I am working in angular version 5.20.
I am using HttpClient instead of Http when providing AdalAngular5 but it still returns the error mentioned above. Also can you set cache location to local storage in adal config ?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.