Verified Commit 2e672cfd authored by Raphael Ochsenbein's avatar Raphael Ochsenbein
Browse files

Added basic implementation to use oidc with ngrx

parent ef33a3d8
......@@ -24,7 +24,17 @@
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
"src/assets",
{
"glob": "**/*",
"input": "src/static",
"output": "/"
},
{
"glob": "oidc-client.min.js",
"input": "node_modules/oidc-client/dist",
"output": "/"
}
],
"styles": [
"src/styles.scss"
......@@ -137,4 +147,4 @@
}
},
"defaultProject": "openid-connect-playground"
}
\ No newline at end of file
}
import { Component } from '@angular/core';
import {OidcFacade} from 'ng-oidc-client';
@Component({
selector: 'app-root',
......@@ -7,4 +8,15 @@ import { Component } from '@angular/core';
})
export class AppComponent {
title = 'openid-connect-playground';
constructor(private oidcFacade: OidcFacade) {}
loginPopup() {
this.oidcFacade.signinPopup();
}
logoutPopup() {
this.oidcFacade.signoutPopup();
}
}
......@@ -7,6 +7,14 @@ import {Log, WebStorageStateStore} from 'oidc-client';
import {EffectsModule} from '@ngrx/effects';
import {NgOidcClientModule} from 'ng-oidc-client';
import {routerReducer, RouterReducerState} from '@ngrx/router-store';
import {OidcGuardService} from './oidc-guard.service';
import {HTTP_INTERCEPTORS} from '@angular/common/http';
import {OidcInterceptorService} from './oidc-interceptor.service';
import {OidcEffectsService} from './oidc-effects.service';
import {metaReducers} from './logout.metareducer';
// Setup done according to https://www.npmjs.com/package/ng-oidc-client
export interface State {
router: RouterReducerState;
......@@ -21,8 +29,8 @@ export const rootStore: ActionReducerMap<State> = {
],
imports: [
BrowserModule,
StoreModule.forRoot(rootStore),
EffectsModule.forRoot([]),
StoreModule.forRoot(rootStore, { metaReducers}),
EffectsModule.forRoot([OidcEffectsService]),
NgOidcClientModule.forRoot({
oidc_config: {
authority: 'https://localhost:5001',
......@@ -42,7 +50,15 @@ export const rootStore: ActionReducerMap<State> = {
},
}),
],
providers: [],
providers: [
OidcGuardService,
{
provide: HTTP_INTERCEPTORS,
useClass: OidcInterceptorService,
multi: true
},
OidcEffectsService,
],
bootstrap: [AppComponent]
})
export class AppModule { }
import {ActionReducer, MetaReducer} from '@ngrx/store';
import {OidcActions} from 'ng-oidc-client';
import {State} from './app.module';
export function logout(reducer: ActionReducer<any>): ActionReducer<any> {
return (state: any, action: any) => {
// Reset state if user logs out
if (action.type === OidcActions.OidcActionTypes.OnUserSignedOut) {
return reducer(undefined, action);
}
return reducer(state, action);
};
}
export const metaReducers: MetaReducer<State>[] = [logout];
import {tap} from 'rxjs/operators';
import {OidcActions} from 'ng-oidc-client';
import {Actions, Effect, ofType} from '@ngrx/effects';
import {Action} from '@ngrx/store';
import {Observable} from 'rxjs';
import {Router} from '@angular/router';
export class OidcEffectsService {
constructor(private actions$: Actions, private router: Router) {}
@Effect({ dispatch: false })
onUserSignedOut$: Observable<Action> = this.actions$.pipe(
ofType(OidcActions.OidcActionTypes.OnUserSignedOut),
tap(args => {
this.router.navigate(['/home']);
})
);
}
import {ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot} from '@angular/router';
import {OidcFacade} from 'ng-oidc-client';
import {Observable, of} from 'rxjs';
import {switchMap, take} from 'rxjs/operators';
export class OidcGuardService implements CanActivate {
constructor(private router: Router, private oidcFacade: OidcFacade) {}
public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean {
return this.oidcFacade.identity$.pipe(
take(1),
switchMap(user => {
console.log('Auth Guard - Checking if user exists', user);
console.log('Auth Guard - Checking if user is expired:', user && user.expired);
if (user && !user.expired) {
return of(true);
} else {
this.router.navigate(['/login']);
return of(false);
}
})
);
}
}
import {switchMap} from 'rxjs/operators';
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
import {Observable} from 'rxjs';
import {OidcFacade} from 'ng-oidc-client';
export class OidcInterceptorService implements HttpInterceptor {
static OidcInterceptorService: any;
constructor(private oidcFacade: OidcFacade) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return this.oidcFacade.identity$.pipe(
switchMap(user => {
if (user && !user.expired && user.access_token) {
req = req.clone({
setHeaders: {
Authorization: `Bearer ${user.access_token}`
}
});
}
return next.handle(req);
})
);
}
}
src/favicon.ico

5.3 KB | W: | H:

src/favicon.ico

1.12 KB | W: | H:

src/favicon.ico
src/favicon.ico
src/favicon.ico
src/favicon.ico
  • 2-up
  • Swipe
  • Onion skin
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Callback</title>
<link rel="icon"
type="image/x-icon"
href="favicon.png">
<script src="oidc-client.min.js"
type="application/javascript"></script>
</head>
<body>
<script>
var Oidc = window.Oidc;
var config = {
userStore: new Oidc.WebStorageStateStore({ store: window.localStorage })
}
if ((Oidc && Oidc.Log && Oidc.Log.logger)) {
Oidc.Log.logger = console;
}
var isPopupCallback = JSON.parse(window.localStorage.getItem('ngoidc:isPopupCallback'));
if (isPopupCallback) {
new Oidc.UserManager(config).signinPopupCallback();
} else {
new Oidc.UserManager(config).signinRedirectCallback().then(t => {
window.location.href = '/';
});
}
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Renew Callback</title>
<link rel="icon"
type="image/x-icon"
href="favicon.png">
</head>
<body>
<script src="oidc-client.min.js"></script>
<script>
var config = {
userStore: new Oidc.WebStorageStateStore({ store: window.localStorage })
}
new Oidc.UserManager(config).signinSilentCallback().catch(function (e) {
console.error(e);
});
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Signout Callback</title>
<link rel="icon"
type="image/x-icon"
href="favicon.png">
<script src="oidc-client.min.js"
type="application/javascript"></script>
</head>
<body>
<script>
var Oidc = window.Oidc;
var config = {
userStore: new Oidc.WebStorageStateStore({ store: window.localStorage })
}
if ((Oidc && Oidc.Log && Oidc.Log.logger)) {
Oidc.Log.logger = console;
}
var isPopupCallback = JSON.parse(window.localStorage.getItem('ngoidc:isPopupCallback'));
if (isPopupCallback) {
new Oidc.UserManager(config).signoutPopupCallback();
} else {
new Oidc.UserManager(config).signoutRedirectCallback().then(test => {
window.location.href = '/';
});
}
</script>
</body>
</html>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment