[ADF-4295] AuthGuardSsoRoleService - Provide a way to check the resorces_access of the jwt token (#4488)

* Provide a way to check the resorces_access of a jwt token

* Add unit test in case the client role is missing or contains a different one

* Improve the documentation related to the AuthGuardSSO
This commit is contained in:
Maurizio Vitale
2019-03-25 17:07:22 +00:00
committed by Eugenio Romano
parent c3bbbe6dab
commit 391094e467
4 changed files with 160 additions and 11 deletions

View File

@@ -116,4 +116,98 @@ describe('Auth Guard SSO role service', () => {
expect(routerService.navigate).not.toHaveBeenCalled();
}));
it('Should canActivate be false hasRealm is true and hasClientRol is false', () => {
const route: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
spyOn(this, 'hasRealmRoles').and.returnValue(true);
spyOn(this, 'hasRealmRolesForClientRole').and.returnValue(false);
route.data = { 'clientRoles': ['appName'], 'roles': ['role1', 'role2'] };
expect(authGuard.canActivate(route, null)).toBeFalsy();
});
it('Should canActivate be false hasRealm is false and hasClientRol is true', () => {
const route: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
spyOn(this, 'hasRealmRoles').and.returnValue(false);
spyOn(this, 'hasRealmRolesForClientRole').and.returnValue(true);
route.data = { 'clientRoles': ['appName'], 'roles': ['role1', 'role2'] };
expect(authGuard.canActivate(route, null)).toBeFalsy();
});
it('Should canActivate be true if both Real Role and Client Role are present int the JWT token', () => {
const route: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
spyOn(storageService, 'getItem').and.returnValue('my-access_token');
spyOn(jwtHelperService, 'decodeToken').and.returnValue({
'realm_access': { roles: ['role1'] },
'resource_access': { fakeapp: { roles: ['role2'] }}
});
route.params = {appName: 'fakeapp'};
route.data = { 'clientRoles': ['appName'], 'roles': ['role1', 'role2'] };
expect(authGuard.canActivate(route, null)).toBeTruthy();
});
it('Should canActivate be false if the Client Role is not present int the JWT token with the correct role', () => {
const route: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
spyOn(storageService, 'getItem').and.returnValue('my-access_token');
spyOn(jwtHelperService, 'decodeToken').and.returnValue({
'realm_access': { roles: ['role1'] },
'resource_access': { fakeapp: { roles: ['role3'] }}
});
route.params = {appName: 'fakeapp'};
route.data = { 'clientRoles': ['appName'], 'roles': ['role1', 'role2'] };
expect(authGuard.canActivate(route, null)).toBeFalsy();
});
describe('ClientRole ', () => {
it('Should be true if the resource_access contains the single role', () => {
spyOn(storageService, 'getItem').and.returnValue('my-access_token');
spyOn(jwtHelperService, 'decodeToken').and.returnValue(
{'resource_access': { fakeapp: { roles: ['role1'] } }
});
const result = authGuard.hasRealmRolesForClientRole('fakeapp', ['role1'] );
expect(result).toBeTruthy();
});
it('Should be true if the resource_access contains at least one of the roles', () => {
spyOn(storageService, 'getItem').and.returnValue('my-access_token');
spyOn(jwtHelperService, 'decodeToken').and.returnValue(
{'resource_access': { fakeapp: { roles: ['role1'] } }
});
const result = authGuard.hasRealmRolesForClientRole('fakeapp', ['role1', 'role2'] );
expect(result).toBeTruthy();
});
it('Should be false if the resource_access does not contain the role', () => {
spyOn(storageService, 'getItem').and.returnValue('my-access_token');
spyOn(jwtHelperService, 'decodeToken').and.returnValue(
{'resource_access': { fakeapp: { roles: ['role3'] } }
});
const result = authGuard.hasRealmRolesForClientRole('fakeapp', ['role1', 'role2']);
expect(result).toBeFalsy();
});
it('Should be false if the resource_access does not contain the client role related to the app', () => {
spyOn(storageService, 'getItem').and.returnValue('my-access_token');
spyOn(jwtHelperService, 'decodeToken').and.returnValue(
{'resource_access': { anotherfakeapp: { roles: ['role1'] } }
});
const result = authGuard.hasRealmRolesForClientRole('fakeapp', ['role1', 'role2']);
expect(result).toBeFalsy();
});
});
});

View File

@@ -27,12 +27,24 @@ export class AuthGuardSsoRoleService implements CanActivate {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
let hasRole = false;
let hasRealmRole = false;
let hasClientRole = true;
if (route.data) {
const rolesToCheck = route.data['roles'];
hasRole = this.hasRoles(rolesToCheck);
if (route.data['roles']) {
const rolesToCheck = route.data['roles'];
hasRealmRole = this.hasRealmRoles(rolesToCheck);
}
if (route.data['clientRoles']) {
const clientRoleName = route.params[route.data['clientRoles']];
const rolesToCheck = route.data['roles'];
hasClientRole = this.hasRealmRolesForClientRole(clientRoleName, rolesToCheck);
}
}
hasRole = hasRealmRole && hasClientRole;
if (!hasRole && route.data && route.data['redirectUrl']) {
this.router.navigate(['/' + route.data['redirectUrl']]);
}
@@ -43,33 +55,56 @@ export class AuthGuardSsoRoleService implements CanActivate {
constructor(private storageService: StorageService, private jwtHelperService: JwtHelperService, private router: Router) {
}
getRoles(): string[] {
getRealmRoles(): string[] {
const access = this.getValueFromToken<any>('realm_access');
const roles = access ? access['roles'] : [];
return roles;
}
getClientRoles(client: string): string[] {
const clientRole = this.getValueFromToken<any>('resource_access')[client];
const roles = clientRole ? clientRole['roles'] : [];
return roles;
}
getAccessToken(): string {
return this.storageService.getItem('access_token');
}
hasRole(role: string): boolean {
hasRealmRole(role: string): boolean {
let hasRole = false;
if (this.getAccessToken()) {
const roles = this.getRoles();
hasRole = roles.some((currentRole) => {
const realmRoles = this.getRealmRoles();
hasRole = realmRoles.some((currentRole) => {
return currentRole === role;
});
}
return hasRole;
}
hasRoles(rolesToCheck: string []): boolean {
hasRealmRoles(rolesToCheck: string []): boolean {
return rolesToCheck.some((currentRole) => {
return this.hasRole(currentRole);
return this.hasRealmRole(currentRole);
});
}
hasRealmRolesForClientRole(clientRole: string, rolesToCheck: string []): boolean {
return rolesToCheck.some((currentRole) => {
return this.hasClientRole(clientRole, currentRole);
});
}
hasClientRole(clientRole, role: string): boolean {
let hasRole = false;
if (this.getAccessToken()) {
const clientRoles = this.getClientRoles(clientRole);
hasRole = clientRoles.some((currentRole) => {
return currentRole === role;
});
}
return hasRole;
}
getValueFromToken<T>(key: string): T {
let value;
const accessToken = this.getAccessToken();