Skip to content

Commit e4e2e49

Browse files
committed
add new keycloak silent-sso to increase login verification
1 parent 0386fdf commit e4e2e49

File tree

7 files changed

+85
-38
lines changed

7 files changed

+85
-38
lines changed

frontend/src/app/app-init.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,25 @@ import { UserInfoStore } from './core/user/user-info.store';
44
import { UserDataStore } from './core/user/userdata.store';
55
import { SystemService } from './core/cache/system.service';
66

7-
export function initializer(keycloak: KeycloakService, userInfoStore: UserInfoStore, userDataStore: UserDataStore, _systemService: SystemService): () => Promise<any> {
7+
export function initializer(keycloak: KeycloakService, userInfoStore: UserInfoStore, userDataStore: UserDataStore,
8+
_systemService: SystemService): () => Promise<any> {
89
return (): Promise<any> => {
910
return new Promise(async (resolve, reject) => {
1011
try {
1112
_systemService.checkVersion();
1213
keycloak.keycloakEvents$.subscribe(event => {
1314
if (event.type === KeycloakEventType.OnAuthSuccess) {
14-
userInfoStore.getUserInfo$().subscribe( userInfo => {
15+
userInfoStore.getUserInfo$().subscribe(userInfo => {
1516
userDataStore.loadInitialUserData(userInfo.sub, userInfo.given_name, userInfo.email);
1617
console.log('load initial userInfo');
1718
});
1819
}
1920
if (event.type === KeycloakEventType.OnAuthLogout) {
2021
this.userDataStore.resetUserDataStore();
2122
}
23+
if (event.type === KeycloakEventType.OnTokenExpired) {
24+
keycloak.updateToken(20);
25+
}
2226
});
2327
await keycloak.init({
2428
config: {
@@ -28,10 +32,12 @@ export function initializer(keycloak: KeycloakService, userInfoStore: UserInfoSt
2832
},
2933
initOptions: {
3034
onLoad: 'check-sso',
31-
checkLoginIframe: false
35+
silentCheckSsoRedirectUri:
36+
window.location.origin + '/assets/silent-check-sso.html'
3237
},
3338
bearerExcludedUrls: [
34-
'/api/public'
39+
'/api/public',
40+
'/assets'
3541
]
3642
});
3743
resolve('true');

frontend/src/app/app.component.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,5 +98,5 @@ footer {
9898

9999
.on-top {
100100
position:relative;
101-
z-index: 1000;
101+
z-index: 900;
102102
}

frontend/src/app/app.module.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { SharedModule } from './shared/shared.module';
77
import { CoreModule } from './core/core.module';
88
import { PublicResourcesModule } from './public/public.module';
99
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
10-
import { KeycloakAngularModule, KeycloakService } from 'keycloak-angular';
10+
import { KeycloakAngularModule, KeycloakEventType, KeycloakService } from 'keycloak-angular';
1111
import { initializer } from './app-init';
1212
import { RouterModule } from '@angular/router';
1313
import { PageNotFoundComponent } from './not-found.component';
@@ -28,6 +28,45 @@ import { SnippetNotFoundComponent } from './not-found/snippet-not-found.componen
2828
import { SystemService } from './core/cache/system.service';
2929
import { NewEntryComponent } from './new-entry/new-entry.component';
3030

31+
function initializeKeycloak(keycloak: KeycloakService, userInfoStore: UserInfoStore, userDataStore: UserDataStore,
32+
_systemService: SystemService) {
33+
return () => {
34+
_systemService.checkVersion();
35+
keycloak.keycloakEvents$.subscribe(event => {
36+
if (event.type === KeycloakEventType.OnAuthSuccess) {
37+
userInfoStore.getUserInfo$().subscribe(userInfo => {
38+
userDataStore.loadInitialUserData(userInfo.sub, userInfo.given_name, userInfo.email);
39+
console.log('load initial userInfo');
40+
});
41+
}
42+
if (event.type === KeycloakEventType.OnAuthLogout) {
43+
this.userDataStore.resetUserDataStore();
44+
}
45+
if (event.type === KeycloakEventType.OnTokenExpired) {
46+
keycloak.updateToken(20);
47+
}
48+
});
49+
50+
keycloak.init({
51+
config: {
52+
url: environment.keycloak.url, // .ie: http://localhost:8080/auth/
53+
realm: environment.keycloak.realm, // .ie: master
54+
clientId: environment.keycloak.clientId // .ie: account
55+
},
56+
initOptions: {
57+
onLoad: 'check-sso',
58+
silentCheckSsoRedirectUri:
59+
window.location.origin + '/assets/silent-check-sso.html'
60+
},
61+
bearerExcludedUrls: [
62+
'/api/public',
63+
'/assets'
64+
]
65+
});
66+
}
67+
68+
}
69+
3170
@NgModule({
3271
exports: [
3372
MatChipsModule
Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,35 @@
1-
import {Injectable} from '@angular/core';
2-
import {ActivatedRouteSnapshot, Router, RouterStateSnapshot} from '@angular/router';
3-
import {KeycloakAuthGuard, KeycloakService} from 'keycloak-angular';
4-
import {environment} from '../../../environments/environment';
1+
import { Injectable } from '@angular/core';
2+
import { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from '@angular/router';
3+
import { KeycloakAuthGuard, KeycloakService } from 'keycloak-angular';
4+
import { environment } from '../../../environments/environment';
55

66
@Injectable()
77
export class AuthGuard extends KeycloakAuthGuard {
88
constructor(protected router: Router, protected keycloakAngular: KeycloakService) {
99
super(router, keycloakAngular);
1010
}
1111

12-
isAccessAllowed(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
13-
return new Promise(async (resolve, reject) => {
14-
if (!this.authenticated) {
15-
const options: Keycloak.KeycloakLoginOptions = {};
16-
options.redirectUri = environment.APP_HOME_URL + state.url;
17-
this.keycloakAngular.login(options);
18-
return;
19-
}
12+
public async isAccessAllowed(
13+
route: ActivatedRouteSnapshot,
14+
state: RouterStateSnapshot
15+
) {
16+
// Force the user to log in if currently unauthenticated.
17+
if (!this.authenticated) {
18+
await this.keycloakAngular.login({
19+
redirectUri: window.location.origin + state.url
20+
});
21+
}
2022

21-
const requiredRoles = route.data.roles;
22-
if (!requiredRoles || requiredRoles.length === 0) {
23-
return resolve(true);
24-
} else {
25-
if (!this.roles || this.roles.length === 0) {
26-
resolve(false);
27-
}
28-
let granted = false;
29-
for (const requiredRole of requiredRoles) {
30-
if (this.roles.indexOf(requiredRole) > -1) {
31-
granted = true;
32-
break;
33-
}
34-
}
35-
resolve(granted);
36-
}
37-
});
23+
// Get the roles required from the route.
24+
const requiredRoles = route.data.roles;
25+
26+
// Allow the user to to proceed if no additional roles are required to access the route.
27+
if (!(requiredRoles instanceof Array) || requiredRoles.length === 0) {
28+
return true;
29+
}
30+
31+
// Allow the user to proceed if all the required roles are present.
32+
return requiredRoles.every((role) => this.roles.includes(role));
3833
}
34+
3935
}

frontend/src/app/core/keycloak-service-wrapper.service.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { Injectable } from '@angular/core';
2-
import { HttpClient, HttpHeaders } from '@angular/common/http';
32
import { environment } from '../../environments/environment';
43
import { Router, RouterStateSnapshot } from '@angular/router';
54
import { KeycloakService } from 'keycloak-angular';
@@ -14,7 +13,7 @@ export class KeycloakServiceWrapper {
1413
public login() {
1514
const routerStateSnapshot: RouterStateSnapshot = this.router.routerState.snapshot;
1615
const options: Keycloak.KeycloakLoginOptions = {};
17-
options.redirectUri = environment.APP_HOME_URL + routerStateSnapshot.url;
16+
options.redirectUri = environment.APP_HOME_URL + routerStateSnapshot.url;
1817
this.keycloakService.login(options);
1918
}
2019

frontend/src/app/public/bookmarks/homepage.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<button type="button" class="btn btn-primary btn-sm mr-2" (click)="login('feed')"><i
1111
class="fas fa-unlock"></i> Login / Register
1212
</button> to <strong>Codever</strong>
13-
to see posts with your favorite topics in your feed
13+
to see posts from your favorite topics in your feed
1414
</div>
1515
</div>
1616
<ng-template #showFollowedTags>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<html>
2+
<body>
3+
<script>
4+
parent.postMessage(location.href, location.origin);
5+
</script>
6+
</body>
7+
</html>

0 commit comments

Comments
 (0)