如何在Angular中借助MSAL与Graph API实现单点登录?
在Angular中借助Graph API实现单点登录(SSO)
核心思路
你的项目已经集成Graph API,接下来实现SSO的关键是用微软官方的MSAL库处理认证流程,自动缓存用户凭证,达成首次认证后无需重复登录的效果。
具体实现步骤
安装依赖包
先安装MSAL的Angular适配包和核心浏览器包:npm install @azure/msal-angular @azure/msal-browser配置MSAL模块
在app.module.ts中导入并配置MSAL,填入你的Azure AD应用注册信息和Graph API权限:import { NgModule } from '@angular/core'; import { MsalModule, MsalService, MSAL_INSTANCE } from '@azure/msal-angular'; import { PublicClientApplication } from '@azure/msal-browser'; export function MSALInstanceFactory() { return new PublicClientApplication({ auth: { clientId: '你的应用客户端ID', // 从Azure AD应用注册页获取 authority: 'https://login.microsoftonline.com/你的租户ID', // 租户ID或使用common(适用于个人/工作账户) redirectUri: 'http://localhost:4200' // 与Azure AD中配置的回调地址一致 }, cache: { cacheLocation: 'localStorage', // 用本地存储缓存凭证,跨会话保留登录状态 storeAuthStateInCookie: false } }); } @NgModule({ imports: [ MsalModule.forRoot(MSALInstanceFactory()) ], providers: [ { provide: MSAL_INSTANCE, useFactory: MSALInstanceFactory }, MsalService ] }) export class AppModule { }处理自动登录逻辑
在app.component.ts中初始化认证检查,打开应用时自动读取缓存凭证,无凭证则触发登录:import { Component, OnInit } from '@angular/core'; import { MsalService } from '@azure/msal-angular'; @Component({ selector: 'app-root', templateUrl: './app.component.html' }) export class AppComponent implements OnInit { constructor(private msalService: MsalService) {} ngOnInit(): void { // 检查是否存在已登录账户 const activeAccount = this.msalService.instance.getAllAccounts()[0]; if (!activeAccount) { // 无登录状态,弹出登录窗口 this.msalService.loginPopup({ scopes: ['user.read', 'mail.read'] // 按需添加你的Graph API操作权限 }).subscribe({ next: (res) => console.log('登录成功:', res.account?.username), error: (err) => console.error('登录失败:', err) }); } else { // 已有缓存的登录状态,直接复用 console.log('自动登录成功,当前用户:', activeAccount.username); } } }保护需要认证的路由
用MsalGuard拦截敏感路由,确保只有登录用户能访问:import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { MsalGuard } from '@azure/msal-angular'; import { DashboardComponent } from './dashboard/dashboard.component'; const routes: Routes = [ { path: 'dashboard', component: DashboardComponent, canActivate: [MsalGuard] // 为路由添加认证守卫 } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }携带Token调用Graph API
登录成功后,用MSAL获取的Token发起Graph API请求:import { HttpClient, HttpHeaders } from '@angular/common/http'; import { MsalService } from '@azure/msal-angular'; // 在组件或服务中实现 constructor(private http: HttpClient, private msalService: MsalService) {} fetchUserProfile() { const account = this.msalService.instance.getActiveAccount(); if (!account) return; const accessToken = this.msalService.instance.getAccountById(account.homeAccountId)?.idToken; const headers = new HttpHeaders({ 'Authorization': `Bearer ${accessToken}` }); this.http.get('https://graph.microsoft.com/v1.0/me', { headers }) .subscribe({ next: (profile) => console.log('用户信息:', profile), error: (err) => console.error('获取用户信息失败:', err) }); }
关键注意事项
- 确保Azure AD应用注册中的回调地址与代码里的
redirectUri完全一致 - 缓存位置设为
localStorage可让登录状态在浏览器关闭后保留,实现真正的“一次认证,多次使用” - 权限配置要贴合实际业务需求,避免请求不必要的Graph API权限
内容的提问来源于stack exchange,提问作者amir tariq
相关产品推荐
相关产品推荐

