首页 > 解决方案 > Azure token hasgroups: true ,Adal angular, Graph API,

问题描述

我正在后端开发 Angular 应用程序和 .net。我没有为用户制作表格,而是在 Azure 中注册后使用 Microsoft Azure 登录到应用程序。在 Angular 方面,我使用“microsoft-adal-angular6”库连接到 azure 并返回令牌,一切正常,为了提高安全性,我将此令牌发送到后端,它也连接到 Azure 并验证此令牌在那之后显示数据,直到这里一切都很好,我得到了令牌。

但是,当用户拥有超过 6 个组时,此令牌不具有带有 Id 的属性“组”,而不是它,令牌具有属性 hasgroups:true。我在后端有策略,例如添加新客户,当用户超过 6 个组时,他不能添加客户,错误是 403 禁止。我尝试了很多寻找灵魂。但我没有找到适合我的情况,我知道我需要调用图形 API 来带来所有组,但我没有找到任何真实的例子,只是解释。那么,在这种情况下,您能否告诉我如何解决这个问题。这里是我如何从 Angular 连接到 azure 的代码。

角度:

appModule.ts:

imports: [ MsAdalAngular6Module.forRoot({
  tenant: 'tetant Id of the app in Azure',
  clientId: 'client Id of the app in Azure',
  redirectUri: window.location.origin,
  endpoints: {
    "http://localhost:4211/": "http://localhost:4211/",
  },
  navigateToLoginRequestUrl: false,
  cacheLocation: '<localStorage / sessionStorage>', }),

角度迭代器看起来像:

导出类拦截器实现 HttpInterceptor {

初始令牌;headers = new HttpHeaders({ 'Content-Type': 'application/json' });

构造函数(私有 adalSvc:MsAdalAngular6Service,私有 http:HttpClient,私有路由器:路由器)

{

this.initialToken = sessionStorage.getItem('adal.idtoken') ;

console.log( "initialToken " , this.initialToken); 

}

拦截(请求:HttpRequest,下一个:HttpHandler):Observable> {

if (this.initialToken) {

  request = request.clone({
    setHeaders: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${this.initialToken}`
    }
  });

  }

return next.handle( request ).pipe( tap(() => {},
  (err: any) => {
if (err instanceof HttpErrorResponse) {
    if (err.status !== 401) {
     return;
    }
    this.router.navigate(['']);
  }
}))

}

后端验证令牌:

services.AddAuthentication(sharedOptions =>
            {
                sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
                sharedOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; 
                sharedOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

            })


            .AddJwtBearer(options =>
            {
                options.Audience = "clientId";
                options.Authority = "https://login.microsoftonline.com/tetantId/";

                options.RequireHttpsMetadata = false;

                options.Events = new JwtBearerEvents()
                {
                    OnTokenValidated = context =>
                    {
                        return Task.CompletedTask;
                    }
                };
            });

谢谢您的帮助。

标签: angularjwtadalazure-ad-graph-api

解决方案


如果您使用隐式流并且用户有 6 个或更多组,则它们将不在访问令牌中。由于令牌在 URL 中返回,因此隐式流的限制较小。

在这种情况下,不建议使用groups声明。您可以定义一些应用角色并将角色分配给组。然后该组中的用户将拥有如下声明:

{
  "roles": ["admin"]
}

然后您可以根据用户的角色实现您的授权逻辑。请参阅此处的参考。

当然你也可以调用 Microsoft Graph API 来获取群组信息。

代码应该是这样的:

if (hasGroups)
  Call the Graph to inquire:
    Either about the full group membership OR 
    About membership to a particular group
else
  Access groups directly from the token

请参阅带有 Microsoft Graph 的 Angular 应用示例。有关更多示例,请参见此处


推荐阅读