diff --git a/bun.lockb b/bun.lockb
index a4ad67b..6fd82b0 100755
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/package.json b/package.json
index 232ef91..f1859dd 100644
--- a/package.json
+++ b/package.json
@@ -19,6 +19,7 @@
"@angular/platform-browser-dynamic": "^18.2.0",
"@angular/router": "^18.2.0",
"bootstrap": "^5.3.3",
+ "keycloak-angular": "^16.1.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.10"
diff --git a/public/silent-check-sso.html b/public/silent-check-sso.html
new file mode 100644
index 0000000..75b40d3
--- /dev/null
+++ b/public/silent-check-sso.html
@@ -0,0 +1,3 @@
+
+ balls
+
diff --git a/src/app/app.config.ts b/src/app/app.config.ts
index a1e7d6f..b047b4b 100644
--- a/src/app/app.config.ts
+++ b/src/app/app.config.ts
@@ -1,8 +1,47 @@
-import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
+import { APP_INITIALIZER, ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
+import {KeycloakAngularModule, KeycloakBearerInterceptor, KeycloakService} from "keycloak-angular";
+import { HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
+
+export const initializeKeycloak = (keycloak: KeycloakService) => async () =>
+ keycloak.init({
+ config: {
+ url: 'https://keycloak.szut.dev/auth',
+ realm: 'szut',
+ clientId: 'employee-management-service-frontend',
+ },
+ loadUserProfileAtStartUp: true,
+ initOptions: {
+ onLoad: 'check-sso',
+ silentCheckSsoRedirectUri:
+ window.location.origin + '/silent-check-sso.html',
+ checkLoginIframe: false,
+ redirectUri: 'http://localhost:4200',
+ },
+ });
+
+function initializeApp(keycloak: KeycloakService): () => Promise {
+ return () => initializeKeycloak(keycloak)();
+}
export const appConfig: ApplicationConfig = {
- providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes)]
+ providers: [
+ provideRouter(routes),
+ KeycloakAngularModule,
+ {
+ provide: APP_INITIALIZER,
+ useFactory: initializeApp,
+ multi: true,
+ deps: [KeycloakService]
+ },
+ KeycloakService,
+ provideHttpClient(withInterceptorsFromDi()),
+ {
+ provide: HTTP_INTERCEPTORS,
+ useClass: KeycloakBearerInterceptor,
+ multi: true
+ }
+ ]
};
diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts
index ae2c715..7f0657d 100644
--- a/src/app/app.routes.ts
+++ b/src/app/app.routes.ts
@@ -3,6 +3,8 @@ import { LoginViewComponent } from './components/login-view/login-view.component
import { MitarbeiterverwaltungViewComponent } from './components/mitarbeiterverwaltung-view/mitarbeiterverwaltung-view.component';
import { EmployeeDetailComponent } from './components/employee-detail/employee-detail.component';
import { QualifikatonBearbeitenViewComponent } from './components/qualifikaton-bearbeiten-view/qualifikaton-bearbeiten-view.component';
+import { KeycloakAuthGuard } from 'keycloak-angular';
+import { AuthGuard } from './service/auth.service';
export const routes: Routes = [
{
@@ -12,6 +14,7 @@ export const routes: Routes = [
{
path: "mitarbeiter",
component: MitarbeiterverwaltungViewComponent,
+ canActivate: [AuthGuard],
},
{
path: "mitarbeiterdetails",
@@ -20,5 +23,9 @@ export const routes: Routes = [
{
path: "qualifikationbearbeiten",
component: QualifikatonBearbeitenViewComponent,
+ },
+ {
+ path: "**",
+ redirectTo: '',
}
];
diff --git a/src/app/components/login-view/login-view.component.ts b/src/app/components/login-view/login-view.component.ts
index ffc3ab9..9e9655e 100644
--- a/src/app/components/login-view/login-view.component.ts
+++ b/src/app/components/login-view/login-view.component.ts
@@ -1,4 +1,5 @@
import { Component } from '@angular/core';
+import { KeycloakService } from 'keycloak-angular';
@Component({
selector: 'app-login-view',
@@ -8,5 +9,4 @@ import { Component } from '@angular/core';
styleUrl: './login-view.component.css'
})
export class LoginViewComponent {
-
}
diff --git a/src/app/service/auth.service.ts b/src/app/service/auth.service.ts
new file mode 100644
index 0000000..0179ce9
--- /dev/null
+++ b/src/app/service/auth.service.ts
@@ -0,0 +1,42 @@
+import { Injectable } from '@angular/core';
+import {
+ ActivatedRouteSnapshot,
+ Router,
+ RouterStateSnapshot
+} from '@angular/router';
+import { KeycloakAuthGuard, KeycloakService } from 'keycloak-angular';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class AuthGuard extends KeycloakAuthGuard {
+ constructor(
+ protected override readonly router: Router,
+ protected readonly keycloak: KeycloakService
+ ) {
+ super(router, keycloak);
+ }
+
+ public async isAccessAllowed(
+ route: ActivatedRouteSnapshot,
+ state: RouterStateSnapshot
+ ) {
+ // Force the user to log in if currently unauthenticated.
+ if (!this.authenticated) {
+ await this.keycloak.login({
+ redirectUri: window.location.origin + state.url
+ });
+ }
+
+ // Get the roles required from the route.
+ const requiredRoles = route.data['roles'];
+
+ // Allow the user to proceed if no additional roles are required to access the route.
+ if (!Array.isArray(requiredRoles) || requiredRoles.length === 0) {
+ return true;
+ }
+
+ // Allow the user to proceed if all the required roles are present.
+ return requiredRoles.every((role) => this.roles.includes(role));
+ }
+}