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

关于Angular 13与.NET Core API 5集成Azure AD及自定义认证的需求问询

Angular 13 + .NET Core 5 集成Azure AD SSO与自定义令牌认证实现方案

核心逻辑梳理

Azure AD仅负责身份校验,系统全程使用自定义令牌完成业务操作:

  • 首次通过Azure AD登录:完成本地用户创建,切换为自定义令牌
  • 后续Azure AD登录:直接校验本地用户身份,返回自定义令牌跳转系统
  • 登出需同时清除本地令牌并触发Azure AD登出

前端(Angular 13)实现步骤

1. 集成Azure AD认证依赖

安装MSAL Angular库:

npm install @azure/msal-angular @azure/msal-browser

2. 配置MSAL模块

在app.module.ts中配置Azure AD参数:

import { MsalModule, MsalService, MSAL_INSTANCE } from '@azure/msal-angular';
import { PublicClientApplication } from '@azure/msal-browser';

export function MSALInstanceFactory(): PublicClientApplication {
  return new PublicClientApplication({
    auth: {
      clientId: 'YOUR_AZURE_AD_CLIENT_ID',
      authority: 'https://login.microsoftonline.com/YOUR_TENANT_ID',
      redirectUri: 'http://localhost:4200/auth-callback', // 回调地址
      postLogoutRedirectUri: 'http://localhost:4200/login' // 登出后跳转地址
    }
  });
}

@NgModule({
  imports: [
    MsalModule.forRoot(MSALInstanceFactory())
  ],
  providers: [
    { provide: MSAL_INSTANCE, useFactory: MSALInstanceFactory },
    MsalService
  ]
})
export class AppModule { }

3. 登录流程处理

首次/后续Azure AD登录统一处理

在登录组件中实现登录逻辑:

import { MsalService } from '@azure/msal-angular';
import { HttpClient } from '@angular/common/http';

constructor(private msalService: MsalService, private http: HttpClient) {}

async loginWithAzureAD() {
  const loginResponse = await this.msalService.loginPopup();
  const user = this.msalService.instance.getAllAccounts()[0];
  
  // 提取用户核心标识(用邮箱或Azure AD的oid)
  const userInfo = {
    email: user.username,
    displayName: user.name,
    azureAdOid: user.idTokenClaims.oid
  };

  // 调用后端接口校验/创建用户
  const authResponse = await this.http.post('/api/auth/azure-ad-auth', userInfo).toPromise();
  
  // 存储自定义令牌到本地
  localStorage.setItem('custom-token', authResponse.token);
  
  // 跳转系统首页
  window.location.href = '/dashboard';
}

4. 登出逻辑实现

async logout() {
  // 清除本地自定义令牌
  localStorage.removeItem('custom-token');
  
  // 调用后端登出接口作废令牌(可选)
  await this.http.post('/api/auth/logout', { token: localStorage.getItem('custom-token') }).toPromise();
  
  // 触发Azure AD登出
  await this.msalService.logout();
}

后端(.NET Core 5)实现步骤

1. 配置Azure AD身份校验(可选,用于验证Azure AD用户合法性)

在Startup.cs中添加Azure AD JWT校验:

public void ConfigureServices(IServiceCollection services)
{
  // 原有自定义令牌认证配置保留
  services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer("CustomToken", options => {
      // 原有自定义令牌校验逻辑
    })
    .AddJwtBearer("AzureAD", options => {
      options.Authority = "https://login.microsoftonline.com/YOUR_TENANT_ID";
      options.Audience = "YOUR_AZURE_AD_CLIENT_ID";
    });
}

2. 实现Azure AD认证接口

创建AuthController处理用户校验/注册:

[ApiController]
[Route("api/auth")]
public class AuthController : ControllerBase
{
  private readonly UserManager<ApplicationUser> _userManager;
  private readonly ITokenService _tokenService;
  private readonly IEmailService _emailService;

  public AuthController(UserManager<ApplicationUser> userManager, ITokenService tokenService, IEmailService emailService)
  {
    _userManager = userManager;
    _tokenService = tokenService;
    _emailService = emailService;
  }

  [HttpPost("azure-ad-auth")]
  public async Task<IActionResult> AzureAdAuth([FromBody] AzureAdUserDto userDto)
  {
    // 检查是否存在本地用户
    var existingUser = await _userManager.FindByEmailAsync(userDto.Email);
    
    if (existingUser == null)
    {
      // 创建新用户
      var newUser = new ApplicationUser
      {
        UserName = userDto.Email,
        Email = userDto.Email,
        DisplayName = userDto.DisplayName,
        AzureAdOid = userDto.AzureAdOid
      };
      
      var result = await _userManager.CreateAsync(newUser);
      if (!result.Succeeded) return BadRequest(result.Errors);
      
      // 生成初始密码并发送邮件
      var tempPassword = await _userManager.GeneratePasswordResetTokenAsync(newUser);
      await _emailService.SendLoginCredentialsEmail(newUser.Email, tempPassword);
    }
    
    // 生成自定义令牌
    var token = await _tokenService.GenerateToken(existingUser ?? newUser);
    return Ok(new { Token = token });
  }

  [HttpPost("logout")]
  public IActionResult Logout([FromBody] LogoutDto logoutDto)
  {
    // 将令牌加入黑名单(或依赖令牌过期机制)
    _tokenService.RevokeToken(logoutDto.Token);
    return Ok();
  }
}

3. 保留原有自定义令牌认证体系

确保原有基于自定义令牌的接口授权逻辑不变,所有业务接口仍使用自定义令牌校验:

[Authorize(AuthenticationSchemes = "CustomToken")]
[ApiController]
[Route("api/[controller]")]
public class BusinessController : ControllerBase
{
  // 业务接口逻辑
}

关键注意事项

  • Azure AD的用户标识(如oid或邮箱)需与本地用户表绑定,确保后续登录能准确匹配
  • 自定义令牌需设置合理的过期时间,登出时可通过令牌黑名单机制立即作废
  • 邮件发送需包含初始登录信息,确保用户可切换为本地账号登录

内容的提问来源于stack exchange,提问作者nikudale

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 06:09:50