Secure Angular4 with Keycloak Role or Group

Demo template is available for sale for $50. You can send payment via skype at: czetsuya@gmail.com This article will be an extension of an e...

Demo template is available for sale for $50. You can send payment via skype at: czetsuya@gmail.com

This article will be an extension of an existing one: http://toztech.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:

  1. 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
    }
  2. 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
    }
    }
  3. 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 );
    } );
    }
  4. 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;
    }
    }
  5. 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:
  1. 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: czetsuya@gmail.com

COMMENTS

mas template
Name

amazon,1,angular,8,bigdata,2,business,1,course-spring,27,courses,6,database,4,docker,3,java,50,kafka,1,keycloak,4,microservices,5,mysql,1,neworking,1,nosql,2,php,1,pinned,2,react,3,server management,7,shared drive,1,spring,7,synology,1,troubleshooting,2,web,1,wordpress,1,
ltr
item
toztech: Secure Angular4 with Keycloak Role or Group
Secure Angular4 with Keycloak Role or Group
toztech
https://toztech.blogspot.com/2017/11/secure-angular4-with-keycloak-role-or.html
https://toztech.blogspot.com/
https://toztech.blogspot.com/
https://toztech.blogspot.com/2017/11/secure-angular4-with-keycloak-role-or.html
true
2554149350007112447
UTF-8
Loaded All Posts Not found any posts VIEW ALL Readmore Reply Cancel reply Delete By Home PAGES POSTS View All RECOMMENDED FOR YOU LABEL ARCHIVE SEARCH ALL POSTS Not found any post match with your request Back Home Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sun Mon Tue Wed Thu Fri Sat January February March April May June July August September October November December Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec just now 1 minute ago $$1$$ minutes ago 1 hour ago $$1$$ hours ago Yesterday $$1$$ days ago $$1$$ weeks ago more than 5 weeks ago Followers Follow THIS PREMIUM CONTENT IS LOCKED STEP 1: Share to a social network STEP 2: Click the link on your social network Copy All Code Select All Code All codes were copied to your clipboard Can not copy the codes / texts, please press [CTRL]+[C] (or CMD+C with Mac) to copy Table of Content