几乎没有角色的角JWT

问题描述 投票:1回答:2

我想使用多个角色来访问应用程序中的视图,如果我使用一个角色,则一切正常,但是当我使用多个角色时,视图不提供访问权限

我的模特用户拥有此:

export class User {
    role: Role;                // I change - role: Role[] for few roles
    expiresIn: string;
    aud: string;
    iss: string;
    token?: string;
}

export enum Role {
    Admin = 'admin',
    User = 'user',   
    Engineer = 'engineer'
}

我的后端给我的令牌和角色:

//....
role: (2) ["admin", "engineer"]
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ
//....

如果我在登录方式中使用此选项

tokenInfo['http://schemas.microsoft.com/ws/2008/06/identity/claims/role'][0]   - first element in array

我只有一个角色,并且代码工作正常,但是我可以有许多属于不同角色的用户,并且如果至少有一个角色,我需要应用程序为他们提供访问权限

我处理令牌解码并获得授权服务中的角色

signin(username:string, password:string ) {
    return this.http.post<User>(`${environment.apiUrl}${environment.apiVersion}Profile/Login`, {username, password})    
    .pipe(map(user => {
    if (user && user.token) {
      let tokenInfo = this.getDecodedAccessToken(user.token); // decode token
      this.session = {
        token: user.token,
        role: tokenInfo['http://schemas.microsoft.com/ws/2008/06/identity/claims/role'],     - add this [0]
        expiresIn: tokenInfo.exp,
        aud: tokenInfo.aud,
        iss: tokenInfo.iss,            
      }
      localStorage.setItem('currentUser', JSON.stringify(this.session));
      this.currentUserSubject.next(this.session);         
    }
    return this.session;
    }))
} 

例如简单的脚架

Login() {
    this.auth.signin(this.signinForm.value.email, this.signinForm.value.password)
        .pipe(first())
        .subscribe(
            data => {
                console.log("User is logged in");
                this.router.navigate(['/dashboard']);
                this.loading = false;
            });
  }

不确定我是否正确指定了多个访问角色

//......
{
    path: 'books',
    loadChildren: () => import('./views/books/books.module').then(m => m.BooksModule),
    canActivate: [AuthGaurd],
    data: { roles: [Role.Admin] }  <- work fine if 1 role
},
{
    path: 'person',
    loadChildren: () => import('./views/person/person.module').then(m => m.PersonModule),
    canActivate: [AuthGaurd],    
    data: { roles: [Role.Admin, Role.Engineer] }  <- if have 1 role - admin - open
 },
 {
    path: 'eqip',
    loadChildren: () => import('./views/person/person.module').then(m => m.PersonModule),
    canActivate: [AuthGaurd],    
    data: { roles: [Role.Engineer] }  <- not open becouse only admin role
 },
//......
javascript angular typescript angular-ui-router jwt
2个回答
1
投票

也可能是打字稿枚举不是字符串。因此,将enum与字符串进行比较将永远是不正确的。

您需要使用const enum,因为它会编译为字符串。

尝试更改为

export const enum Role {
    Admin = 'admin',
    User = 'user',   
    Engineer = 'engineer'
}

尽管这确实具有其他含义。https://www.typescriptlang.org/docs/handbook/enums.html#const-enums


0
投票

这实际上取决于您如何处理AuthGuard代码。本指南中提供了有关如何设置身份验证和授权的综合教程:https://jasonwatmore.com/post/2018/11/22/angular-7-role-based-authorization-tutorial-with-example

AuthGuard上可能会遇到问题的较大区域。您可以从我上面共享的链接中获得此示例:

import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';

import { AuthenticationService } from '@/_services';

@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate {
    constructor(
        private router: Router,
        private authenticationService: AuthenticationService
    ) {}

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        const currentUser = this.authenticationService.currentUserValue;
        if (currentUser) {
            // check if route is restricted by role
            if (route.data.roles && route.data.roles.indexOf(currentUser.role) === -1) {
                // role not authorised so redirect to home page
                this.router.navigate(['/']);
                return false;
            }

            // authorised so return true
            return true;
        }

        // not logged in so redirect to login page with the return url
        this.router.navigate(['/login'], { queryParams: { returnUrl: state.url }});
        return false;
    }
}

您还需要确保将正确的角色传递到AuthGuard中。

如果您以后希望有更严格的限制,也可以参考以下指南:How to prevent actions by user role in Angular

希望这会有所帮助!

© www.soinside.com 2019 - 2024. All rights reserved.