Is there a way to easily handle authorization based on roles with the lib angular-auth-oidc-client?
As soon as a user is on the site, I want to identify them, so I use the auto-login-all-routes
guards, and this far everything is ok for me. But I'd like to allow access only if the userData contains a specific role, otherwise redirect to the unauthorized page.
At first I though I could just create a custom version of auto-login-all-routes.guard.ts but as most of the services used are not exported by the module, it doesn't seem to be a good idea.
Do you have any suggestions?
CodePudding user response:
Use 2 guards.
First one to authenticate:
auto-login-all-routes.guard
Then a custom guard to listen oidcSecurityService.userData$
and check for roles.
CodePudding user response:
Here is an example that I'm currently using, not sure if it is what you are looking for.
Routes
{
path: 'import',
component: ImportComponent,
canActivate: [AuthGuard, RoleGuard],
data: { roles: new Set([UserRole.admin, UserRole.developer]) },
},
Guard
@Injectable({
providedIn: 'root',
})
export class RoleGuard implements CanActivate {
constructor(private store: Store<AppState>, private location: Location) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return this.store.select(selectUserRoles).pipe(
debounce((roles) => (roles ? EMPTY : timer(2500))),
map((roles) => {
const permittedRoles = (route.data as RouteData).roles;
if (
roles &&
Array.from(roles.values()).some((role) => permittedRoles.has(role))
) {
return true;
} else {
alert(
`Requires one of the following roles: ${Array.from(permittedRoles)
.map((role) => getRoleName(role))
.join(', ')}`
);
this.location.back();
return false;
}
}),
first()
);
}
}