Tech-Today
Secure Angular4 with Keycloak Role or Group
Demo template is available for sale for $50. You can send payment via skype at: [email protected]This article will be an extension of an existing one: http://czetsuya-tech.blogspot.com/2017/10/how-to-secure-angular-app-using.html.
Normally in the front-end side (Angular), we are only concern whether a user is authenticated or not. Authorization whether a user has enough access to a given REST resource is configured in the api side. But what if we want to secure the front-end urls nonetheless? One of the many solution is to create a guard and either add an authorization code in canLoad or canActivate. In this article we will deal with canLoad, as we are lazy-loading our modules (please refer to Angular documentation for more information).
In this particular example, we are checking for the group claim tied to a user. Role would also do, but I normally used that on the REST api side.
Here are the steps:
- Create a permission-guard model that we will use when defining the route
export interface PermissionGuard {
Only?: Array string>,
Except?: Array string>,
RedirectTo?: string | Function
}
- Add the route in your app-routing.module.ts file, and define the Permission model in the data attribute.
{
path: 'dashboard/employee',
canLoad: [AuthGuard],
loadChildren: 'app/module/dashboard/employee/employee.module#EmployeeModule',
data: {
Permission: {
Only: ['employee'],
RedirectTo: '403'
} as PermissionGuard
}
}
- In our keycloak.service, add the following methods. It checks if a user is a member of a group specified in the PermissionGuard.
static hasGroup( groupName: string ): boolean {
return KeycloakService.auth.authz != null &&
KeycloakService.auth.authz.authenticated
&& KeycloakService.auth.authz.idTokenParsed.groups.indexOf( "/" + groupName ) !== -1 ? true : false;
}
static hasGroups( groupNames: Array ): boolean {
return groupNames.some( v => {
if ( typeof v === "string" )
return KeycloakService.hasGroup( v );
} );
}
- Going back to the auth-guard.service, let's modify the canLoad method to process the authorization. In here we use the previously defined method to check if the current logged user is a member of an specific group.
canLoad( route: Route ): boolean {
if ( KeycloakService.auth.loggedIn && KeycloakService.auth.authz.authenticated ) {
this.logger.info( "user has been successfully authenticated" );
} else {
KeycloakService.login();
return false;
}
this.logger.info( "checking authorization" );
let data = route.data["Permission"] as PermissionGuard;
if ( Array.isArray( data.Only ) && Array.isArray( data.Except ) ) {
throw "Can't use both 'Only' and 'Except' in route data.";
}
if ( Array.isArray( data.Only ) ) {
let hasDefined = KeycloakService.hasGroups( data.Only )
console.log("hasDefined="+hasDefined);
if ( hasDefined )
return true;
if ( data.RedirectTo && data.RedirectTo !== undefined )
this.router.navigate( [data.RedirectTo] );
return false;
}
if ( Array.isArray( data.Except ) ) {
let hasDefined = KeycloakService.hasGroups( data.Except )
if ( !hasDefined )
return true;
if ( data.RedirectTo && data.RedirectTo !== undefined )
this.router.navigate( [data.RedirectTo] );
return false;
}
}
- An additional bonus is having a directive that we can use in the UI side to hide / show an element when a user is either a member of a group or not
import { Directive, OnInit, ElementRef, Input } from '@angular/core';
import { KeycloakService } from 'app/core/auth/keycloak.service';
@Directive( {
selector: '[hasGroup]'
} )
export class HasGroupDirective implements OnInit {
@Input( 'hasGroup' ) group: string;
@Input( 'hasGroups' ) groups: string;
constructor( private element: ElementRef, ) { }
ngOnInit() {
if ( KeycloakService.hasGroup( this.group ) ) {
this.element.nativeElement.style.display = '';
} else {
this.element.nativeElement.style.display = 'none';
}
}
}
Questions:
- What is 403? It's an additional route to redirect when a user is not authorized.
{ path: '403', component: ForbiddenComponent },
Note: This article is inspired by ng2-permission.
Demo template is available for sale for $50. You can send payment via skype at: [email protected]
-
Secure Spring Boot Rest Project With Keycloak
1. OverviewIn this blog, we will cover the basics of securing a Spring project with Keycloak using keycloak-spring-boot-starter and keycloak-spring-security-adapter.2. LimitationKeycloak is already a well-documented topic that needs no further write up....
-
Multi-layout In Angular5
How to implement a multi-layout feature in Angular5. A common use case for this is when you have a different layout for your public and secured pages. For example, your secured page could have a menu on the left side. Or you have a page that doesn't...
-
Display A Byte[] Image From A Rest Web Service
This tutorial will not delve into angular nor will we discuss what a directive is. We will not try to explain what a rest web service is. Instead we will provide a demonstration via actual code, how we can consume a rest service from angular that returns...
-
Secure Angular4 App With Keycloak
Demo template is available for sale for $50. You can send payment via skype at:
[email protected] Disclaimer: This is not a tutorial on how to setup an Angular^4 project, nor are we going to discuss how to setup a Keycloak server. Needless to say, you...
-
C# Converting A Date To Timestamp And How To Create An Md5 Function
A always use these 2 methods so I'm gonna paste them here. I don't remember if I change some lines in these code but I'm sure I got them from Microsoft hmmm already forget about it. DateTime -> TimeStamp /// /// method for converting a System.DateTime...
Tech-Today