jmurphzyo / angular2oidcclient Goto Github PK
View Code? Open in Web Editor NEWA simple demonstration of using IdentityModel/oidc-client with angular 2
License: GNU General Public License v3.0
A simple demonstration of using IdentityModel/oidc-client with angular 2
License: GNU General Public License v3.0
Thank you for your oidc-client angular example. when I change config to userStore: new WebStorageStateStore({ store: localStorage}) It does not work as expected. Could you please assist the problem.
How to use it with proxy config in angular cli
Hello,
I am using your code for login using identity server.
I am able to make logout working but how can i redirect back to my application main page after logout.
const settings: any = {
authority: "https://Machinename/IdentityServerAuth',
client_id: 'ApplicationName',
redirect_uri: "https://Machinename/ApplicationName" + '/public/auth.html',
silent_redirect_uri: "https://Machinename/ApplicationName" + '/public/silent-renew.html',
post_logout_redirect_uri: "https://Machinename/ApplicationName" + '/public/signout-callback.html',
response_type: 'id_token token',
scope: 'openid email'
automaticSilentRenew: true,
silentRequestTimeout: 10000,
filterProtocolClaims: true,
loadUserInfo: true
};
This is what i am using so it will be great if u can guide where exactly i need to provide application url.
Hi @jmurphzyo,
I am building an Angular 4 app, I am done with most of the part.
Can yo please tell me how we can add a client secret so that it is protected.
Thanks in advance.
Hi @jmurphzyo, first of all thanks for the amazing work you have done.
I am building an angular 2 app with hybrid flow, it would be a great help if you can please guide/suggest on how to achieve that.
I have taken a look at this example and i understand a few things in auth.service.ts file and i understand that it is made for implicit flow if i am right.
Waiting for your reply :-)
When clicking on the startSigninMainWindow button and after logging in through my IdentityServer implementation, I get a javascript error that UserManager is not defined on Auth.html/Auth.js
I've tried to call authService.endSigninMainWindow() in ngOnInit of my Angular 2 component "callback", but I receive the following error on Chrome console:
No id_token in response at t._processSigninParams
I checked my browser and found it passed as queryParam along with the rest of the data:
.../#/pages/callback?id_token=...&access_token=....&scope=....
What Am I missing?
The line this.authHeaders.append('Content-Type', 'application/json'); will get appended every api call and malforms the header request. I would suggest putting it in the _setAuthHeaders(user: any) instead.
private _setAuthHeaders(user: any) {
this.authHeaders = new Headers();
this.authHeaders.append('Authorization', user.token_type + " " + user.access_token);
}
private _setRequestOptions(options?: RequestOptions) {
this.authHeaders.append('Content-Type', 'application/json');
if (options) {
options.headers.append(this.authHeaders.keys[0], this.authHeaders.values[0]);
}
else {
options = new RequestOptions({ headers: this.authHeaders, body: "" });
}
return options;
}
Running the project I was getting:
ERROR in ./src/main.ts
Module not found: Error: Can't resolve './environments/environment' in 'C:\Projects\IdentityServer\Angular2OidcClient\src'
@ ./src/main.ts 4:0-57
@ multi main
I fixed it by changing line 5 of main.ts with:
import { environment } from './app/environments/environment';
(I appreciate the effort on this - thanks!)
auth.html gives a 404 on assets/oidc-client.min.js. This can be fixed by either changing
{"glob":"**/*.js", "input":"../node_modules/oidc-client/dist/","output":"./"},
to
{"glob":"**/*.js", "input":"../node_modules/oidc-client/dist/","output":"./assets"},
in .angular-cli.json
or
<script src="assets/oidc-client.min.js"></script>
to
<script src="oidc-client.min.js"></script>
in auth.html
However after fixing this I'm then stumped by the error "Log is not defined" after the auth redirect.
I get an error when building the project using ng build
or attempting to run the project using ng serve
.
I've attached the stacktrace here: stack.txt
Hmm, I'm very much a novice, so this could be a dumb or misdirected question.
I wanted to try to connect this to google, just as a test.
From google, I have a "clientId" and a "clientSecret".
Can you tell me how those match to settings of authority, clientId etc, as defined in auth.service.ts
I tried multiple combinations, with no luck.
Hi there,
did not see any code that can talk to amazon aws using a a authority + client id + client secret using OidcClientOptions. Please help.
Is there any way that I can achieve this?
I am new with angular 2 and my web app right now is using systemjs and light server.
so i am trying to adopot what you have to work for me.
I have most of the files added to my project and the typescript compiler is happy.
but at runtime i see s couple of 404 errors.
404 get /traceur
404 get /app/aunauthorized.js
but i am not sure what the error mean in terms of bringing in your code and the related changes i need to make.
if you could possibly make a sample that is using system js and light server that would be great!
then it would help me see if i am lacking some things.
i am wondering about the polyfills and the babel stuff ... that might be part of what i have not correctly imported / configured??
I did the npm ... install -- save for each of them
thanks for any advide or hints on what i need to look at.
Hi,
I am having issue with your example for angular 4. I copied basically all your code and added callback urls to angular-cli.json so callback works for angular2. It redirects correctly and I see key values in session / local storage. But I am unable to get anything back and or see anything in my headers. Can you help?
auth.service.ts
import { Injectable, EventEmitter } from '@angular/core';
import { Http, Headers, RequestOptions, Response } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { UserManager, Log, MetadataService, User, WebStorageStateStore } from 'oidc-client';
import { environment } from '../../../environments/environment';
const settings: any = {
client_id: 'testClient',
scope: 'openid profile email PhxAppMgrScope',
response_type: 'id_token token',
redirect_uri: 'http://localhost:4200/auth.html',
silent_redirect_uri: 'http://localhost:4200/silent-renew-callback.html',
post_logout_redirect_uri: 'http://localhost:4200/',
authority: 'https://phenomenexauthserver.azurewebsites.net',
userStore: new WebStorageStateStore({ store: window.localStorage || window.sessionStorage }),
automaticSilentRenew: true,
loadUserInfo: true,
accessTokenExpiringNotificationTime: 4,
filterProtocolClaims: true
};
@Injectable()
export class AuthenticationService {
mgr: UserManager = new UserManager(settings);
userLoadededEvent: EventEmitter<User> = new EventEmitter<User>();
currentUser: User;
loggedIn = false;
authHeaders: Headers;
constructor(private http: Http) {
this.mgr.getUser()
.then((user) => {
if (user) {
this.loggedIn = true;
this.currentUser = user;
this.userLoadededEvent.emit(user);
} else {
this.loggedIn = false;
}
})
.catch((err) => {
this.loggedIn = false;
});
this.mgr.events.addUserLoaded(user => {
this.currentUser = user;
if (!environment.production) {
console.log('authService addUserLoaded', user);
}
});
this.mgr.events.addUserUnloaded((e) => {
if (!environment.production) {
console.log('user unloaded');
}
this.loggedIn = false;
});
}
clearState() {
this.mgr.clearStaleState().then(function () {
console.log('clearStateState success');
}).catch(function (e) {
console.log('clearStateState error', e.message);
});
}
getUser() {
this.mgr.getUser().then((user) => {
console.log('got user', user);
this.currentUser = user;
this.userLoadededEvent.emit(user);
}).catch(function (err) {
console.log(err);
});
}
isLoggedInObs(): Observable<boolean> {
return Observable.fromPromise(this.mgr.getUser()).map<User, boolean>((user) => {
if (user) {
return true;
} else {
return false;
}
});
}
removeUser() {
this.mgr.removeUser().then(() => {
this.userLoadededEvent.emit(null);
console.log('user removed');
}).catch(function (err) {
console.log(err);
});
}
login() {
if (this.mgr === null) {
this.mgr = new Oidc.UserManager(settings)
}
this.mgr.signinRedirect();
}
logout() {
this.mgr.signoutRedirect().then(function (resp) {
console.log('signed out', resp);
setTimeout(5000, () => {
console.log('testing to see if fired...');
});
}).catch(function (err) {
console.log(err);
});
};
endSignoutMainWindow() {
this.mgr.signoutRedirectCallback().then(function (resp) {
console.log('signed out', resp);
}).catch(function (err) {
console.log(err);
});
};
/**
* Example of how you can make auth request using angulars http methods.
* @param options if options are not supplied the default content type is application/json
*/
AuthGet(url: string, options?: RequestOptions): Observable<Response> {
if (options) {
options = this._setRequestOptions(options);
} else {
options = this._setRequestOptions();
}
return this.http.get(url, options);
}
/**
* @param options if options are not supplied the default content type is application/json
*/
AuthPut(url: string, data: any, options?: RequestOptions): Observable<Response> {
const body = JSON.stringify(data);
if (options) {
options = this._setRequestOptions(options);
} else {
options = this._setRequestOptions();
}
return this.http.put(url, body, options);
}
/**
* @param options if options are not supplied the default content type is application/json
*/
AuthDelete(url: string, options?: RequestOptions): Observable<Response> {
if (options) {
options = this._setRequestOptions(options);
} else {
options = this._setRequestOptions();
}
return this.http.delete(url, options);
}
/**
* @param options if options are not supplied the default content type is application/json
*/
AuthPost(url: string, data: any, options?: RequestOptions): Observable<Response> {
const body = JSON.stringify(data);
if (options) {
options = this._setRequestOptions(options);
} else {
options = this._setRequestOptions();
}
return this.http.post(url, body, options);
}
private _setAuthHeaders(user: any) {
this.authHeaders = new Headers();
this.authHeaders.append('Authorization', user.token_type + ' ' + user.access_token);
this.authHeaders.append('Content-Type', 'application/json');
}
public _setRequestOptions(options?: RequestOptions) {
if (options) {
options.headers.append(this.authHeaders.keys[0], this.authHeaders.values[0]);
} else {
options = new RequestOptions({ headers: this.authHeaders, body: '' });
}
return options;
}
}
angular-cli.json
"assets": [
{ "glob": "**/*", "input": "./assets/", "output": "./assets/" },
{ "glob":"**/*.js", "input":"../node_modules/oidc-client/dist/","output":"./" },
{ "glob": "**/*", "input": "./assets/", "output": "./assets/" },
{ "glob": "favicon.ico", "input": "./", "output": "./" },
{ "glob": "auth.html", "input": "./", "output": "./" },
{ "glob": "silent-renew-callback.html", "input": "./", "output": "./" },
{ "glob": "**/*.js", "input": "./scripts/", "output": "./"}
],
my project demo is here, let me know if you find anything. https://github.com/premiumwd/a
I was attempting to modify the sample code to make a POST request to my API. The HTTP Post did not include any content and the POST header content-length was set to 0. I modified auth.service.ts and removed body: '' from RequestOptions in _setRequestOptions as that appeared to prevent the Angular post function from properly setting the body. After making the change, the POST api call worked successfully.
auth.service.ts:
private _setRequestOptions(options?: RequestOptions) {
if (this.loggedIn) {
this._setAuthHeaders(this.currentUser);
}
if (options) {
options.headers.append(this.authHeaders.keys[0], this.authHeaders.values[0]);
} else {
options = new RequestOptions({ headers: this.authHeaders }); // Removed: body: ''
}
return options;
}
Based on #17, you mentioned the SPA didn't received the notification.
But it focused me deeply.
Based on your codes in this repo (https://github.com/jmurphzyo/Angular2OidcClient/blob/master/src/app/shared/services/auth.service.ts), you will call singinRedirect() for the first sign-in, correct?
Then, when shall call to signinSilent()? Or, am I totally wrong?
Thank you so much in advance, Alva
Hi, may I ask you, if you hav eupgraded your solution already to angular 4.0 ?
I use a similar apporach with oidc client and a auth.html.
Since I switched to angular 4 it is not working anymore.
The redirect to identity server works fine, but when I signed in and get redirected to auth.html
I get the following error:
I have no idea why this is happening :(
Is it a bug in angular router ?
Take a look at using serviceWorker / MessageChannel to abstract user data and notify the oidc client running inside the angular app to load the user. This would allow for a very small iframe foot print and its only requirement would be parsing urls and decoding jwts. The url history would still remain clean.
Hello,
I am able to make this project work on my machine using angular cli build and using my custom IdentityServer on localhost.
Now i am trying to use this project by copying required files to VisualStudio based project which uses VisualStudio build to create dist bundles.
i am using this way in index.html
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
How can i include odic-client.js in this?
Any sample solution will be helpful.
my systemjs.config looks like this
/**
System configuration for Angular samples
Adjust as necessary for your application needs.
*/
(function (global) {
System.config({
paths: {
// paths serve as alias
'npm:': 'node_modules/'
},
// map tells the System loader where to look for things
map: {
// our app is within the app folder
app: 'app',
// angular bundles
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
'@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/http': 'npm:@angular/http/bundles/http.umd.js',
'@angular/router': 'npm:@angular/router/bundles/router.umd.js',
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
'@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js',
// other libraries
'rxjs': 'npm:rxjs',
'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js'
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
main: './main.js',
defaultExtension: 'js'
},
rxjs: {
defaultExtension: 'js'
}
}
});
})(this);
and this is package.json
{
"name": "ng2-quickstart",
"version": "1.0.0",
"description": "QuickStart package.json from the documentation, supplemented with testing support",
"scripts": {
"start": "tsc && concurrently "tsc -w" "lite-server" ",
"docker-build": "docker build -t ng2-quickstart .",
"docker": "npm run docker-build && docker run -it --rm -p 3000:3000 -p 3001:3001 ng2-quickstart",
"pree2e": "npm run webdriver:update",
"e2e": "tsc && concurrently "http-server -s" "protractor protractor.config.js" --kill-others --success first",
"lint": "tslint ./app/**/*.ts -t verbose",
"lite": "lite-server",
"test": "tsc && concurrently "tsc -w" "karma start karma.conf.js"",
"test-once": "tsc && karma start karma.conf.js --single-run",
"tsc": "tsc",
"tsc:w": "tsc -w",
"webdriver:update": "webdriver-manager update"
},
"keywords": [],
"author": "",
"licenses": [
{
"type": "MIT",
"url": "https://github.com/angular/angular.io/blob/master/LICENSE"
}
],
"dependencies": {
"@angular/common": "~2.1.2",
"@angular/compiler": "~2.1.2",
"@angular/core": "~2.1.2",
"@angular/forms": "~2.1.2",
"@angular/http": "~2.1.2",
"@angular/platform-browser": "~2.1.2",
"@angular/platform-browser-dynamic": "~2.1.2",
"@angular/router": "~3.1.2",
"@angular/upgrade": "~2.1.2",
"angular-in-memory-web-api": "~0.1.13",
"systemjs": "0.19.40",
"core-js": "^2.4.1",
"oidc-client": "^1.2.0",
"reflect-metadata": "^0.1.8",
"rxjs": "5.0.0-beta.12",
"zone.js": "^0.6.26"
},
"devDependencies": {
"concurrently": "^3.1.0",
"lite-server": "^2.2.2",
"typescript": "^2.0.3",
"canonical-path": "0.0.2",
"http-server": "^0.9.0",
"tslint": "^3.15.1",
"lodash": "^4.16.4",
"jasmine-core": "~2.4.1",
"karma": "^1.3.0",
"karma-chrome-launcher": "^2.0.0",
"karma-cli": "^1.0.1",
"karma-htmlfile-reporter": "^0.3.4",
"karma-jasmine": "^1.0.2",
"karma-jasmine-html-reporter": "^0.2.2",
"karma-script-launcher": "~0.1.0",
"karma-html2js-preprocessor": "~0.1.0",
"protractor": "4.0.9",
"webdriver-manager": "10.2.5",
"rimraf": "^2.5.4",
"@types/core-js": "^0.9.34",
"@types/node": "^6.0.46",
"@types/jasmine": "^2.5.36",
"@types/selenium-webdriver": "^2.53.33"
},
"repository": {}
}
endSignoutMainWindow() {
this.authService.endSigninMainWindow();
}
Hello,
I have an typsescript error on build by the angular-cli :
TypeScript error: /angular2Client/node_modules/oidc-client/oidc-client.d.ts(32,15): Error TS1112: A class member cannot be declared optional.
My oidc import in my authSerice :
import { UserManager, User } from 'oidc-client';
any idea ?
I have the same error when I build this repo
Thank's
Hi! Is it possible to have a sample of silent refresh? I tried to follow scott brady's tutorial but nothing work.
Thanks
In the typings for oidc, there is a user interface. You can import it at the top of the auth.service.ts
import { UserManager, Log, MetadataService, User } from 'oidc-client';
You can close this, I just wanted to make an enhancement suggestion.
Hi guys,
I've just tried cloning the angular app v4 (https://github.com/jmurphzyo/Angular2OidcClient/tree/ng4) and then I ran "npm install" and "npm start" so, I'm getting the following errors:
ERROR in /home/myuser/Documents/repos/github/oidc-angular-client/node_modules/oidc-client/index.d.ts (41,26): Initializers are not allowed in ambient contexts.
/home/myuser/Documents/repos/github/oidc-angular-client/node_modules/oidc-client/index.d.ts (42,27): Initializers are not allowed in ambient contexts.
/home/myuser/Documents/repos/github/oidc-angular-client/node_modules/oidc-client/index.d.ts (43,26): Initializers are not allowed in ambient contexts.
/home/myuser/Documents/repos/github/oidc-angular-client/node_modules/oidc-client/index.d.ts (44,26): Initializers are not allowed in ambient contexts.
/home/myuser/Documents/repos/github/oidc-angular-client/node_modules/oidc-client/index.d.ts (45,27): Initializers are not allowed in ambient contexts.
/home/myuser/Documents/repos/github/oidc-angular-client/node_modules/oidc-client/index.d.ts (129,14): Cannot find name 'Partial'.
/home/myuser/Documents/repos/github/oidc-angular-client/node_modules/oidc-client/index.d.ts (164,22): Cannot find name 'Record'.
ERROR in /home/myuser/Documents/repos/github/oidc-angular-client/src/app/shared/services/auth.service.ts (62,37): Argument of type '(e: any) => void' is not assignable to parameter of type 'UserUnloadedCallback'.
I've tried many things I could not manage to fix this... Could help me please?
Hi,
First of all: great work!
I have just one question: I couldn't find out which version of oidc-client-js you are using.
It just works fine, but your oidc-client.min.js is different from all tagged versions of oidc-client.min.js from IdentityModel.
First off, thanks for putting this together and sharing.
I'm trying to get it to work using the ng4 branch you've set up. The only thing not working so far is automatic silent renewal of the tokens. What appears to be happening is the renewal works fine, but the Angular instance of UserManager never sees the event it needs to know the iframe requests are succeeding. I suspect this is because the redirect response is handled in another instance of UserManager created in a static html page. I updated the code slightly to use a different callback page for the silent renewal as in this example.
I'm working to debug this, but was curious if anyone has gotten this to work?
Here's a another issue that seems related (just for reference):
IdentityModel/oidc-client-js#250 (comment)
Don't work with IE 11
Error: Object doesn't support property or method 'from'
Code: auth.html, line 13,
File: oidc-client.min.js, Line: 1, Column: 1665
I'm trying to implement OidClient so I'm studying this great example app. Now I've come across an issue where the app redirects me to /unauthenticated even though I should have a token. Steps to reproduce:
I'm trying to find what I'm missing here with some breakpoints, one in AuthGuardService and one AuthService. I noticed the following: when hitting F5, the AuthGuardService checks this.authService.loggedIn
before AuthService has the chance to set loggedIn = true
in its constructor, causing the redirect.
Am I overlooking something or is this behavior a bug?
Are there examples of using AuthGet, AuthPut and such? The "_setAuthHeaders" method in auth.server.ts isnt wired up to anything that I can see.
Hi, I get Error: Cannot match any routes. URL Segment: 'id_token' after login, both on angular 2.4.8 and angular ^4.0.0. Please help. Thanks
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.