diff --git a/ClientApp/ClientApp/app/app.module.client.ts b/ClientApp/ClientApp/app/app.module.client.ts
index be23bb0..90ec4c0 100644
--- a/ClientApp/ClientApp/app/app.module.client.ts
+++ b/ClientApp/ClientApp/app/app.module.client.ts
@@ -4,10 +4,6 @@ import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { sharedConfig } from './app.module.shared';
-import { AuthService } from './components/services/auth.service';
-import { GlobalEventsManager } from './components/services/global.events.manager';
-import { AuthGuardService } from './components/services/auth-guard.service';
-
@NgModule({
bootstrap: sharedConfig.bootstrap,
declarations: sharedConfig.declarations,
@@ -20,7 +16,7 @@ import { AuthGuardService } from './components/services/auth-guard.service';
providers: [
{ provide: 'ORIGIN_URL', useValue: location.origin },
{ provide: 'API_URL', useValue: "http://localhost:5001/api/" },
- AuthService, AuthGuardService, GlobalEventsManager
+ ...sharedConfig.providers
]
})
export class AppModule {
diff --git a/ClientApp/ClientApp/app/app.module.server.ts b/ClientApp/ClientApp/app/app.module.server.ts
index b532b5f..6468367 100644
--- a/ClientApp/ClientApp/app/app.module.server.ts
+++ b/ClientApp/ClientApp/app/app.module.server.ts
@@ -2,10 +2,6 @@ import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';
import { sharedConfig } from './app.module.shared';
-import { AuthService } from './components/services/auth.service';
-import { GlobalEventsManager } from './components/services/global.events.manager';
-import { AuthGuardService } from './components/services/auth-guard.service';
-
@NgModule({
bootstrap: sharedConfig.bootstrap,
declarations: sharedConfig.declarations,
@@ -14,7 +10,7 @@ import { AuthGuardService } from './components/services/auth-guard.service';
...sharedConfig.imports
],
providers: [
- AuthService, AuthGuardService, GlobalEventsManager
+ ...sharedConfig.providers
]
})
export class AppModule {
diff --git a/ClientApp/ClientApp/app/app.module.shared.ts b/ClientApp/ClientApp/app/app.module.shared.ts
index f11327f..145efa2 100644
--- a/ClientApp/ClientApp/app/app.module.shared.ts
+++ b/ClientApp/ClientApp/app/app.module.shared.ts
@@ -6,12 +6,10 @@ import { NavMenuComponent } from './components/navmenu/navmenu.component';
import { HomeComponent } from './components/home/home.component';
import { FetchDataComponent } from './components/fetchdata/fetchdata.component';
import { CounterComponent } from './components/counter/counter.component';
-import { CallbackComponent } from './components/callback/callback.component';
import { UnauthorizedComponent } from './components/unauthorized/unauthorized.component';
+import { AuthModule } from 'angular-auth-oidc-client';
import { AuthService } from './components/services/auth.service';
-import { GlobalEventsManager } from './components/services/global.events.manager';
-import { AuthGuardService } from './components/services/auth-guard.service';
export const sharedConfig: NgModule = {
bootstrap: [ AppComponent ],
@@ -21,19 +19,18 @@ export const sharedConfig: NgModule = {
CounterComponent,
FetchDataComponent,
HomeComponent,
- CallbackComponent,
UnauthorizedComponent
],
imports: [
+ AuthModule.forRoot(),
RouterModule.forRoot([
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
- { path: 'callback', component: CallbackComponent },
{ path: 'unauthorized', component: UnauthorizedComponent },
{ path: 'counter', component: CounterComponent },
- { path: 'fetch-data', component: FetchDataComponent, canActivate:[AuthGuardService] },
+ { path: 'fetch-data', component: FetchDataComponent },
{ path: '**', redirectTo: 'home' }
])
],
- providers: [ AuthService, AuthGuardService, GlobalEventsManager ]
+ providers: [ AuthService ]
};
diff --git a/ClientApp/ClientApp/app/components/callback/callback.component.ts b/ClientApp/ClientApp/app/components/callback/callback.component.ts
deleted file mode 100644
index 779aad3..0000000
--- a/ClientApp/ClientApp/app/components/callback/callback.component.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { Component } from '@angular/core';
-import { AuthService } from '../services/auth.service'
-
-@Component({
- selector: 'callback',
- template: ''
-})
-
-export class CallbackComponent {
- constructor (private _authService: AuthService){
- _authService.endSigninMainWindow();
- }
-}
\ No newline at end of file
diff --git a/ClientApp/ClientApp/app/components/fetchdata/fetchdata.component.ts b/ClientApp/ClientApp/app/components/fetchdata/fetchdata.component.ts
index d302f88..6e85727 100644
--- a/ClientApp/ClientApp/app/components/fetchdata/fetchdata.component.ts
+++ b/ClientApp/ClientApp/app/components/fetchdata/fetchdata.component.ts
@@ -9,8 +9,8 @@ import { AuthService } from '../services/auth.service';
export class FetchDataComponent {
public forecasts: WeatherForecast[];
- constructor(http: Http, @Inject('API_URL') apiUrl: string, authService: AuthService) {
- authService.AuthGet(apiUrl + 'SampleData/WeatherForecasts').subscribe(result => {
+ constructor(authService: AuthService, @Inject('API_URL') apiUrl: string) {
+ authService.get(apiUrl + 'SampleData/WeatherForecasts').subscribe(result => {
this.forecasts = result.json() as WeatherForecast[];
});
}
diff --git a/ClientApp/ClientApp/app/components/navmenu/navmenu.component.html b/ClientApp/ClientApp/app/components/navmenu/navmenu.component.html
index 2fad08f..ec53cb8 100644
--- a/ClientApp/ClientApp/app/components/navmenu/navmenu.component.html
+++ b/ClientApp/ClientApp/app/components/navmenu/navmenu.component.html
@@ -13,29 +13,19 @@
diff --git a/ClientApp/ClientApp/app/components/navmenu/navmenu.component.ts b/ClientApp/ClientApp/app/components/navmenu/navmenu.component.ts
index b792c03..863afb3 100644
--- a/ClientApp/ClientApp/app/components/navmenu/navmenu.component.ts
+++ b/ClientApp/ClientApp/app/components/navmenu/navmenu.component.ts
@@ -1,32 +1,45 @@
-import { Component } from '@angular/core';
-import { AuthService } from '../services/auth.service'
-import { GlobalEventsManager } from '../services/global.events.manager'
+import { Component, OnInit, OnDestroy } from '@angular/core';
+import { Subscription } from 'rxjs/Subscription';
+
+import { AuthService } from '../services/auth.service';
+
@Component({
selector: 'nav-menu',
templateUrl: './navmenu.component.html',
styleUrls: ['./navmenu.component.css']
})
-export class NavMenuComponent {
- public _loggedIn: boolean = false;
-
- constructor (
- private _authService: AuthService,
- private _globalEventsManager: GlobalEventsManager) {
- _globalEventsManager.showNavBarEmitter.subscribe((mode)=>{
- // mode will be null the first time it is created, so you need to igonore it when null
- if (mode !== null) {
- console.log("Global Event, sent: " + mode);
- this._loggedIn = mode;
- }
- });
- }
-
- public login(){
- this._authService.startSigninMainWindow();
- }
-
- public logout(){
- this._authService.startSignoutMainWindow();
- }
+export class NavMenuComponent implements OnInit, OnDestroy {
+ isAuthorizedSubscription: Subscription;
+ isAuthorized: boolean;
+
+ constructor(public authService: AuthService) {
+ }
+
+ ngOnInit() {
+ this.isAuthorizedSubscription = this.authService.getIsAuthorized().subscribe(
+ (isAuthorized: boolean) => {
+ this.isAuthorized = isAuthorized;
+ });
+
+ if (window.location.hash) {
+ this.authService.authorizedCallback();
+ }
+ }
+
+ ngOnDestroy(): void {
+ this.isAuthorizedSubscription.unsubscribe();
+ }
+
+ public login() {
+ this.authService.login();
+ }
+
+ public refreshSession() {
+ this.authService.refreshSession();
+ }
+
+ public logout() {
+ this.authService.logout();
+ }
}
\ No newline at end of file
diff --git a/ClientApp/ClientApp/app/components/services/auth-guard.service.ts b/ClientApp/ClientApp/app/components/services/auth-guard.service.ts
deleted file mode 100644
index ab165e1..0000000
--- a/ClientApp/ClientApp/app/components/services/auth-guard.service.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { Injectable, Component } from '@angular/core';
-import { CanActivate, Router } from '@angular/router';
-
-import { AuthService } from './auth.service';
-
-@Injectable()
-export class AuthGuardService implements CanActivate {
-
- constructor(private authService: AuthService, private router: Router) {
- }
-
- canActivate() {
- if (this.authService.loggedIn) {
- return true;
- }
- else {
- this.router.navigate(['unauthorized']);
- }
- }
-}
\ No newline at end of file
diff --git a/ClientApp/ClientApp/app/components/services/auth.service.ts b/ClientApp/ClientApp/app/components/services/auth.service.ts
index 7ded7b6..435352a 100644
--- a/ClientApp/ClientApp/app/components/services/auth.service.ts
+++ b/ClientApp/ClientApp/app/components/services/auth.service.ts
@@ -1,134 +1,83 @@
-import { Injectable, EventEmitter, Component } from '@angular/core';
+import { Injectable, Component, OnInit, OnDestroy } from '@angular/core';
import { Http, Headers, RequestOptions, Response } from '@angular/http';
import { Observable } from 'rxjs/Rx';
-import { Router } from "@angular/router";
-import { UserManager, Log, MetadataService, User } from 'oidc-client';
-import { GlobalEventsManager } from './global.events.manager';
-
-const settings: any = {
- authority: 'http://localhost:5000',
- client_id: 'ng',
- redirect_uri: 'http://localhost:5002/callback',
- post_logout_redirect_uri: 'http://localhost:5002/home',
- response_type: 'id_token token',
- scope: 'openid profile apiApp',
-
- silent_redirect_uri: 'http://localhost:5002/silent-renew.html',
- automaticSilentRenew: true,
- accessTokenExpiringNotificationTime: 4,
- // silentRequestTimeout:10000,
-
- filterProtocolClaims: true,
- loadUserInfo: true
-};
+import { Subscription } from 'rxjs/Subscription';
+
+import { OidcSecurityService, OpenIDImplicitFlowConfiguration } from 'angular-auth-oidc-client';
@Injectable()
-export class AuthService {
- loggedIn = false;
- mgr: UserManager;
- userLoadedEvent = new EventEmitter();
- currentUser: User;
- authHeaders: Headers;
-
- constructor(
- private http: Http,
- private router: Router,
- private globalEventsManager: GlobalEventsManager) {
- if (typeof window !== 'undefined') {
- //instance needs to be created within the if clause
- //otherwise you'll get a sessionStorage not defined error.
- this.mgr = new UserManager(settings);
- this.mgr
- .getUser()
- .then((user) => {
- if (user) {
- this.currentUser = user;
- this.userLoadedEvent.emit(user);
- }
- })
- .catch((err) => {
- console.log(err);
- });
- this.mgr.events.addUserUnloaded((e) => {
- //if (!environment.production) {
- console.log("user unloaded");
- //}
+export class AuthService implements OnInit, OnDestroy {
+ isAuthorizedSubscription: Subscription;
+ isAuthorized: boolean;
+
+ constructor(public oidcSecurityService: OidcSecurityService,
+ private http: Http) {
+
+ const openIDImplicitFlowConfiguration = new OpenIDImplicitFlowConfiguration();
+ openIDImplicitFlowConfiguration.stsServer = 'http://localhost:5000';
+
+ openIDImplicitFlowConfiguration.redirect_url = 'http://localhost:5002/callback';
+ // The Client MUST validate that the aud (audience) Claim contains its client_id value registered at the Issuer identified by the iss (issuer) Claim as an audience.
+ // The ID Token MUST be rejected if the ID Token does not list the Client as a valid audience, or if it contains additional audiences not trusted by the Client.
+ openIDImplicitFlowConfiguration.client_id = 'ng';
+ openIDImplicitFlowConfiguration.response_type = 'id_token token';
+ openIDImplicitFlowConfiguration.scope = 'openid profile apiApp';
+ openIDImplicitFlowConfiguration.post_logout_redirect_uri = 'http://localhost:5002/home';
+ openIDImplicitFlowConfiguration.start_checksession = true;
+ openIDImplicitFlowConfiguration.silent_renew = true;
+ openIDImplicitFlowConfiguration.startup_route = '/home';
+ // HTTP 403
+ openIDImplicitFlowConfiguration.forbidden_route = '/forbidden';
+ // HTTP 401
+ openIDImplicitFlowConfiguration.unauthorized_route = '/unauthorized';
+ openIDImplicitFlowConfiguration.log_console_warning_active = true;
+ openIDImplicitFlowConfiguration.log_console_debug_active = false;
+ // id_token C8: The iat Claim can be used to reject tokens that were issued too far away from the current time,
+ // limiting the amount of time that nonces need to be stored to prevent attacks.The acceptable range is Client specific.
+ openIDImplicitFlowConfiguration.max_id_token_iat_offset_allowed_in_seconds = 10;
+
+ this.oidcSecurityService.setupModule(openIDImplicitFlowConfiguration);
+ }
+
+ ngOnInit() {
+ this.isAuthorizedSubscription = this.oidcSecurityService.getIsAuthorized().subscribe(
+ (isAuthorized: boolean) => {
+ this.isAuthorized = isAuthorized;
});
+
+ if (window.location.hash) {
+ this.oidcSecurityService.authorizedCallback();
}
}
- clearState() {
- this.mgr.clearStaleState().then(() => {
- console.log('clearStateState success');
- }).catch(e => {
- console.log('clearStateState error', e.message);
- });
+ ngOnDestroy(): void {
+ this.isAuthorizedSubscription.unsubscribe();
}
- getUser() {
- this.mgr.getUser().then((user) => {
- console.log("got user");
- this.userLoadedEvent.emit(user);
- }).catch(err => {
- console.log(err);
- });
+ authorizedCallback() {
+ this.oidcSecurityService.authorizedCallback();
}
- removeUser() {
- this.mgr.removeUser().then(() => {
- this.userLoadedEvent.emit(null);
- console.log("user removed");
- }).catch(err => {
- console.log(err);
- });
+ getIsAuthorized(): Observable {
+ return this.oidcSecurityService.getIsAuthorized();
}
- startSigninMainWindow() {
- this.mgr.signinRedirect({ data: 'some data' }).then(() => {
- console.log("signinRedirect done");
- }).catch(err => {
- console.log(err);
- });
+ login() {
+ console.log('start login');
+ this.oidcSecurityService.authorize();
}
- endSigninMainWindow() {
- if (typeof window !== 'undefined') {
- this.mgr.signinRedirectCallback().then((user) => {
- console.log("signed in");
- this.loggedIn = true;
- this.globalEventsManager.showNavBar(this.loggedIn);
- this.router.navigate(['home']);
- }).catch(err => {
- console.log(err);
- });
- }
+ refreshSession() {
+ console.log('start refreshSession');
+ this.oidcSecurityService.authorize();
}
- startSignoutMainWindow() {
- this.mgr.signoutRedirect().then(resp => {
- console.log("signed out", resp);
- setTimeout(5000, () => {
- console.log("testing to see if fired...");
+ logout() {
+ console.log('start logoff');
+ this.oidcSecurityService.logoff();
+ }
- });
- }).catch(err => {
- console.log(err);
- });
- };
-
- endSignoutMainWindow() {
- this.mgr.signoutRedirectCallback().then(resp => {
- console.log("signed out", resp);
- }).catch(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 {
+ get(url: string, options?: RequestOptions): Observable {
if (options) {
options = this.setRequestOptions(options);
}
@@ -138,10 +87,7 @@ export class AuthService {
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 {
+ put(url: string, data: any, options?: RequestOptions): Observable {
let body = JSON.stringify(data);
if (options) {
@@ -153,11 +99,7 @@ export class AuthService {
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 {
+ delete(url: string, options?: RequestOptions): Observable {
if (options) {
options = this.setRequestOptions(options);
}
@@ -167,10 +109,7 @@ export class AuthService {
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 {
+ post(url: string, data: any, options?: RequestOptions): Observable {
let body = JSON.stringify(data);
if (options) {
@@ -182,22 +121,31 @@ export class AuthService {
return this.http.post(url, body, options);
}
-
- private setAuthHeaders(user: User) {
- this.authHeaders = new Headers();
- this.authHeaders.append('Authorization', user.token_type + " " + user.access_token);
- this.authHeaders.append('Content-Type', 'application/json');
- }
-
private setRequestOptions(options?: RequestOptions) {
if (options) {
- options.headers.append(this.authHeaders.keys[0], this.authHeaders.values[0]);
+ this.appendAuthHeader(options.headers);
}
else {
- //setting default authentication headers
- this.setAuthHeaders(this.currentUser);
- options = new RequestOptions({ headers: this.authHeaders, body: "" });
+ options = new RequestOptions({ headers: this.getHeaders(), body: "" });
}
return options;
}
+
+ private getHeaders() {
+ let headers = new Headers();
+ headers.append('Content-Type', 'application/json');
+ this.appendAuthHeader(headers);
+ return headers;
+ }
+
+ private appendAuthHeader(headers: Headers) {
+ const token = this.oidcSecurityService.getToken();
+
+ if (token == '') return;
+
+ const tokenValue = 'Bearer ' + token;
+ headers.append('Authorization', tokenValue);
+ }
+
+
}
\ No newline at end of file
diff --git a/ClientApp/ClientApp/app/components/services/global.events.manager.ts b/ClientApp/ClientApp/app/components/services/global.events.manager.ts
deleted file mode 100644
index 4fb04b0..0000000
--- a/ClientApp/ClientApp/app/components/services/global.events.manager.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { Injectable } from '@angular/core';
-import { BehaviorSubject } from "rxjs/BehaviorSubject";
-import { Observable } from "rxjs/Observable";
-
-@Injectable()
-export class GlobalEventsManager {
-
- private _showNavBar: BehaviorSubject = new BehaviorSubject(null);
- public showNavBarEmitter: Observable = this._showNavBar.asObservable();
-
- constructor() {}
-
- showNavBar(ifShow: boolean) {
- this._showNavBar.next(ifShow);
- }
-}
\ No newline at end of file
diff --git a/ClientApp/ClientApp/app/components/unauthorized/unauthorized.component.ts b/ClientApp/ClientApp/app/components/unauthorized/unauthorized.component.ts
index 4ea66c2..1912fbf 100644
--- a/ClientApp/ClientApp/app/components/unauthorized/unauthorized.component.ts
+++ b/ClientApp/ClientApp/app/components/unauthorized/unauthorized.component.ts
@@ -1,6 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { Location } from '@angular/common';
-import { AuthService } from '../services/auth.service';
@Component({
selector: 'app-unauthorized',
@@ -8,7 +7,7 @@ import { AuthService } from '../services/auth.service';
})
export class UnauthorizedComponent implements OnInit {
- constructor(private location: Location, private service: AuthService) {
+ constructor(private location: Location) {
}
@@ -16,7 +15,7 @@ export class UnauthorizedComponent implements OnInit {
}
login() {
- this.service.startSigninMainWindow();
+ //this.service.startSigninMainWindow();
}
goback() {
diff --git a/ClientApp/package-lock.json b/ClientApp/package-lock.json
index 4a13723..3f0216e 100644
--- a/ClientApp/package-lock.json
+++ b/ClientApp/package-lock.json
@@ -1,5 +1,5 @@
{
- "name": "WebApplicationBasic",
+ "name": "AngularCoreIdentityServerClient",
"version": "0.0.0",
"lockfileVersion": 1,
"dependencies": {
@@ -81,6 +81,18 @@
"version": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
"integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
},
+ "angular-auth-oidc-client": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/angular-auth-oidc-client/-/angular-auth-oidc-client-1.3.1.tgz",
+ "integrity": "sha512-zr/GH2aCwlLnaNnsChtlNjtFs9YTqPENCHKOp8Z/URLOFDsQy53exA20103FFG75OKgBEohXtAYRdlh4dPN3Ag==",
+ "dependencies": {
+ "jsrsasign": {
+ "version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-7.2.1.tgz",
+ "integrity": "sha1-tNgtGdwUglUmMiUSS1zYhVRvbME="
+ }
+ }
+ },
"angular2-template-loader": {
"version": "https://registry.npmjs.org/angular2-template-loader/-/angular2-template-loader-0.6.2.tgz",
"integrity": "sha1-wNROkP/w+sleiyPwQ6zaf9HFHXw="
diff --git a/ClientApp/package.json b/ClientApp/package.json
index 5233eac..f341a26 100644
--- a/ClientApp/package.json
+++ b/ClientApp/package.json
@@ -1,5 +1,5 @@
{
- "name": "WebApplicationBasic",
+ "name": "AngularCoreIdentityServerClient",
"version": "0.0.0",
"dependencies": {
"@angular/animations": "4.1.2",
@@ -41,7 +41,6 @@
"webpack-hot-middleware": "2.18.0",
"webpack-merge": "4.1.0",
"zone.js": "0.8.10",
- "oidc-client": "1.3.0",
- "babel-polyfill": "6.23.0"
+ "angular-auth-oidc-client": "^1.3.1"
}
}