.net - 基于角色的导航项

标签 .net angular

我正在学习使用 .NET 和 Angular 进行开发,但在涉及基于 Angular 色的菜单项时遇到了障碍。我有路由设置并处于事件状态,试图访问其 Angular 色不提供访问权限的区域的用户被阻止进入。这一切都有效。我遇到的问题是确保他们看不到那些他们无权访问的区域的导航链接。 (如果有帮助,我将使用 CoreUI 管理主题作为基础)。

我的项目有 4 个 Angular 色:

  • 全局管理员
  • 客户管理员
  • 位置管理员
  • 仅限报告

访问由 .NET 应用程序中的 Core Identity 控制。在 Angular 方面,我设置了一个 Angular 色指令,用于使用此指令控制导航链接的查看,并为需要的任何 Angular 色添加 *appHasRole="['GlobalAdmin']"。这不起作用,因为我的侧边栏通过从 _nav.ts 文件中获取它们来构建我的链接。

有人能帮我添加这个功能吗?我什至尝试过为每个 Angular 色使用单独的 _nav 文件,我知道这不是最佳的,并且很快发现如果某人有多个 Angular 色,则会显示两个导航栏。

这就是我的导航系统目前的构建方式。

_nav.ts(请注意,Management 及其子级需要 GlobalAdmin Angular 色,Inspections 需要 LocationsAdmin Angular 色作为示例)。

import { INavData } from '@coreui/angular';

export const navItems: INavData[] = [
  {
    name: 'Dashboard',
    url: '/dashboard',
    icon: 'icon-speedometer',
    badge: {
      variant: 'info',
      text: 'NEW'
    }
  },
  {
    title: true,
    name: 'Licensing'
  },
  {
    name: 'Manage',
    url: '/manage',
    icon: 'icon-settings',
    children: [
      {
        name: 'Register',
        url: '/manage/register',
        icon: 'icon-star'
      },
      {
        name: 'Clients',
        url: '/manage/clients',
        icon: 'icon-user'
      },
      {
        name: 'Locations',
        url: '/manage/locations',
        icon: 'icon-location-pin'
      }
    ]
  },
  {
    title: true,
    name: 'Site Management'
  },
  {
  name: 'Inspections',
    url: '/inspections',
    icon: 'icon-magnifying-glass',
    children: [
      {
        name: 'Setup',
        url: '/inspections/setup',
        icon: 'icon-cursor'
      },
      {
        name: 'Reports',
        url: '/inspections/reports',
        icon: 'icon-cursor'
      }
    ]
  }

显示 SPA 并包含侧边栏的默认布局组件:

  <app-sidebar #appSidebar [fixed]="true" [display]="'lg'" [minimized]="sidebarMinimized" (minimizedChange)="toggleMinimize($event)">
    <app-sidebar-nav [navItems]="navItems" *appHasRole="['GlobalAdmin']" [perfectScrollbar] [disabled]="appSidebar.minimized"></app-sidebar-nav>
    <app-sidebar-minimizer></app-sidebar-minimizer>
  </app-sidebar>

包含 Angular 色策略的 .NET API startup.cs 文件:

services.AddAuthorization(options =>
            {
                options.AddPolicy("RequireGlobalAdminRole", policy => policy.RequireRole("GlobalAdmin"));
                options.AddPolicy("RequireClientAdminRole", policy => policy.RequireRole("GlobalAdmin", "ClientAdmin"));
                options.AddPolicy("RequireLocationAdminRole", policy => policy.RequireRole("GlobalAdmin", "ClientAdmin", "LocationAdmin"));
                options.AddPolicy("RequireReportsOnlyRole", policy => policy.RequireRole("GlobalAdmin", "ClientAdmin", "LocationAdmin", "ReportsOnly"));
            });

如有任何帮助,我们将不胜感激。我已经为此苦苦思索了 4 天,试图找出一种方法。

编辑:app-sidebar-nav.d.ts

import { OnChanges, SimpleChanges } from '@angular/core';
import { Router } from '@angular/router';
import { INavData } from './app-sidebar-nav';
import * as ɵngcc0 from '@angular/core';
export declare class AppSidebarNavComponent implements OnChanges {
    router: Router;
    navItems: INavData[];
    _sidebarBav: boolean;
    role: string;
    navItemsArray: INavData[];
    constructor(router: Router);
    ngOnChanges(changes: SimpleChanges): void;
    static ɵfac: ɵngcc0.ɵɵFactoryDef<AppSidebarNavComponent>;
    static ɵcmp: ɵngcc0.ɵɵComponentDefWithMeta<AppSidebarNavComponent, 
"app-sidebar-nav, cui-sidebar-nav", never, { 'navItems': "navItems", 
'role': "role" }, {}, never>;
}

//# sourceMappingURL=app-sidebar-nav.component.d.ts.map

最佳答案

我遇到过类似的情况,我想为每个菜单项添加 Angular 色和权限,以确保用户只有一个菜单,其中仅包含允许他们查看的项目。顶部接受的答案很接近,但没有雪茄,因为建议 *ngIf 所在的位置。在遇到这个之后,我终于实现了一个相当简单的解决方案:https://github.com/coreui/coreui-free-angular-admin-template/issues/161

  1. 我创建了一个接口(interface)来扩展 INavData:

    export interface MyINavData extends INavData {
       role?: string;
       permissions?: string[]; 
     }
    
  2. 创建服务:

     import { navigation } from '@app/_nav';
      @Injectable({
        providedIn: 'root'
      })
     export class AppSidebarService {
         items$: Observable<MyINavData[]>;
          navItems = navigation;
    
      constructor(private authService: AuthenticationService) {
         this.items$ = this.getSidebarItems();
      }
    
      private getSidebarItems(): Observable<MyINavData []> {
        let navItems: MyINavData [] = new Array<MyINavData >();
        this.navItems.forEach((item) =>{
            //...do some logic here          
        });
        return of(navItems);
     }
    

  3. 更新了调用边栏的 .html 页面:

    <!--<app-sidebar-nav [navItems]="navItems"...</app-sidebar-nav>-->
    <app-sidebar-nav [navItems]="sidebar.items$ | async" ...</app-sidebar-nav> 
    
  4. 确保服务已注入(inject)到调用组件中。

     constructor(..., private sidebarService: AppSidebarService)
    

关于.net - 基于角色的导航项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59441708/

相关文章:

angular - 将 HTML 传递到 Mat 对话框

angular - 如何使用Angular 2自动执行 Electron 应用程序的工作流程

使用 EventEmitter 处理 Angular 4 事件

.net - 具有更好 LINQ 性能的 SortedSet/SortedList?

c# - 我们还应该使用服务器端网格还是 Javascript 网格?

.net - 使用 PowerShell 或 VBS 从 HTML 文件中提取表

c# - 使用 WCF 的 REST 服务 - 可选的查询字符串参数?

c# - .NET 将 Enter 键解释为文本框上的 Tab

数百万的 Angular 管道格式

angular - 重新加载 Angular 应用程序时,总是转到根页面而忽略路由