angular - 如何使用 @azure/msal-angular 获取用户的 AAD 成员资格
问题描述
我正在使用@azure/msal-angular@0.1.4
(Microsoft Authentication Library for Angular)在我的 Angular 8 应用程序中启用 AAD 身份验证。到目前为止,我的数据库中只有一个名为 emp(id、fname、lname、email)的表,并且我使用 .net core 作为后端。
我确实创建了 2 个应用程序注册,一个用于我的 SPA,另一个用于我的 API。我已经公开了 API 并将我的 AD 中的用户图委托权限设置为拥有 user.Read 和 user.ReadAll。
我的 msaluser 服务如下所示:
import { Injectable } from '@angular/core';
import * as Msal from 'msal';
import { environment } from 'src/environments/environment';
import { Observable } from 'rxjs';
@Injectable()
export class MsaluserService {
private accessToken: any;
public clientApplication: Msal.UserAgentApplication = null;
public clientMembership: Msal.User = null;
constructor() {
this.clientApplication = new Msal.UserAgentApplication(
environment.uiClienId,
'https://login.microsoftonline.com/' + environment.tenantId,
this.authCallback,
{
storeAuthStateInCookie: true,
});
}
public GetAccessToken(): Observable<any> {
if (sessionStorage.getItem('msal.idtoken') !== undefined && sessionStorage.getItem('msal.idtoken') != null) {
this.accessToken = sessionStorage.getItem('msal.idtoken');
}
return this.accessToken;
}
public authCallback(errorDesc, token, error, tokenType) {
if (token) {
} else {
console.log(error + ':' + errorDesc);
}
}
public getCurrentUserFullName() {
const user = this.clientApplication.getUser();
alert(user.name);
}
public getCurrentUserEmail() {
const user = this.clientApplication.getUser();
alert(user.displayableId)
}
public getCurrentUserGroups() {
// TO BE FETCHED
// TO BE FETCHED
// TO BE FETCHED
}
public logout() {
this.clientApplication.logout();
}
我的应用模块如下所示
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { environment } from 'src/environments/environment';
import { MsalModule, MsalInterceptor } from '@azure/msal-angular';
import { HttpClientModule, HttpClient, HTTP_INTERCEPTORS } from '@angular/common/http';
import { MsaluserService } from '../_services/msaluser.service';
export const protectedResourceMap: any =
[
[environment.baseUrl, environment.scopeUri]
];
@NgModule({
declarations: [
AppComponent
],
imports: [
MsalModule.forRoot({
clientID: environment.uiClienId,
authority: 'https://login.microsoftonline.com/' + environment.tenantId,
protectedResourceMap: protectedResourceMap,
redirectUri: environment.redirectUrl
}),
BrowserModule,
AppRoutingModule,
HttpClientModule
],
providers: [
HttpClient,
MsaluserService,
{ provide: HTTP_INTERCEPTORS, useClass: MsalInterceptor, multi: true }
],
bootstrap: [AppComponent]
})
export class AppModule { }
我的路线有一个canActivate: [MsalGuard]
在我的 component.html 中,我正在调用这些服务,并且一切似乎都运行良好。但是,我试图在我的 msaluser 服务的构造函数中获取所有用户的 AAD 成员资格,以便我可以调用此函数
public getCurrentUserGroups() {
// TO BE FETCHED
}
当我注入 msaluser 服务时,来自我想要的任何组件。你能告诉我我应该写什么代码,getCurrentUserGroups()
这样我就可以获得登录用户的 AAD 成员资格吗?
你应该知道我的开发环境数组是这样的
export const environment = {
production: false,
baseUrl:'http://localhost:5000/',
scopeUri: ['api://<API_APPLICATION_ID>/<NAME>'],
tenantId: '<TENANT_ID>',
uiClienId: '<SPA_APPLICATION_ID>',
redirectUrl: 'http://localhost:4200'
};
更新
这是我试图调用的方法,但我收到未经授权的请求,尽管 accessToken 是有效的 JWT 令牌
getCurrentUserGroups(): Observable<any[]> {
this.httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + this.msalService.GetAccessToken()
})
};
console.log(this.msalService.GetAccessToken());
return this.http.get('https://graph.microsoft.com/v1.0/users/' + this.msalService.getCurrentUserId() + '/getMemberObjects', this.httpOptions)
.pipe((response: any) => {
return response;
});
}
这是解码令牌的屏幕截图,它确实具有属性[hasgroups]
,因此我应该能够使用我的 JWT 令牌来查询 Microsoft Graph 并获取安全组..
我使用这个令牌从我的后端存储库(.net 核心)中获取员工信息,如下所示:
getEmployees(): Observable<Emp[]> {
this.httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + this.msalService.GetAccessToken()
})
};
return this.http.get(this.baseUrl + 'emps/', this.httpOptions)
.pipe((response: any) => {
return response;
});
}
它正在正确地进行身份验证并获取数据。
解决方案
首先,您的访问令牌用于调用您的 Web API,而不是 Microsoft Graph。
并且根据您的代码,这this.accessToken
似乎是 id 令牌而不是访问令牌。
所以恐怕我们不能getCurrentUserGroups()
直接修改方法来实现您的要求。
如果您想获取用户的 AAD 组,最简单的方法是按照此处的说明在您的令牌中包含组声明。
您只需修改 Azure AD 应用程序清单中的“groupMembershipClaims”字段:
"groupMembershipClaims": "SecurityGroup"
然后令牌将包含使用所属组的 ID,如下所示:
{
"groups": ["{group id}"]
}
在该getCurrentUserGroups()
方法中,尝试使用类似user.groups
.
但是您只能在此处获取组 ID。所以可能需要提前通过配置文件关联组id和组名。
事实上,还有另一种更好的方式将 Groups 和 Roles 结合起来。您可以定义一些应用角色并将角色分配给组。然后组中的用户将拥有“角色”声明。
在这里查看另一个类似的帖子。
推荐阅读
- performance - 从大 Json 数据中快速搜索 Vue
- excel - 未经授权的用户访问隐藏的工作表
- jquery - 如何比较和验证每个位置的每个选定字符是否不同?
- ios - 如何调试网络扩展
- r - 如何使用 RSiteCatalyst 包中的 Queue DataWarehouse 函数从 Adobe Analtics 将数据直接提取到 R 中?
- javascript - 变量内的函数
- r - 自动化 Mann Whitney U 测试以获取大量数据集
- css - 为什么连字符不适用于 Windows 上的 Chrome?
- r - 如何在 r 中使用 svyby 根据其他 2 列的值找到 1 列的中值?
- python - 计算一年中的周数(处理一年的第一周)