如何解决如何使用@ azure / msal-angular
我正在使用@azure/msal-angular@0.1.4
(用于Angular的Microsoft身份验证库)在Angular 8应用程序中启用AAD身份验证。到目前为止,我的数据库中只有1个名为emp的表(id,fname,lname,email),并且我使用.net core作为后端。
我确实为我的SPA创建了2个应用程序注册,其中一个为我的API创建了应用程序注册。我已经公开了该API,并在我的广告中将User Graph委托权限设置为具有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]
,这些服务似乎一切正常。但是,我试图在我的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网上论坛,最简单的方法是按照here的说明将网上论坛声明加入令牌中。
您只需要修改Azure AD应用程序应用程序清单中的“ groupMembershipClaims”字段:
"groupMembershipClaims": "SecurityGroup"
然后令牌将包含使用所属的组的ID,如下所示:
{
"groups": ["{group id}"]
}
在getCurrentUserGroups()
方法中,尝试使用类似user.groups
的东西。
但是您只能在此处获取组ID。因此,您可能需要通过配置文件预先关联组ID和组名。
实际上,还有另一种更好的方式将组和角色结合在一起。您可以define some app roles并将角色分配给组。然后,该组中的用户将具有“角色”声明。
参见另一则类似的帖子here。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。