You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 12:02:17