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

同一Azure注册应用下,Angular生成的MSAL令牌如何让ASP.NET Core MVC复用身份验证

解决方案:Azure AD 跨应用共享登录状态

方案一:利用Azure AD原生SSO会话

这是最推荐的方案,依赖Azure AD在浏览器中设置的域级别SSO cookie,让MVC应用自动识别已登录状态:

  • 配置ASP.NET Core MVC的OpenID Connect中间件,确保和Angular应用使用同一个Azure注册应用的ClientId、Authority,同时启用必要参数:
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(options =>
    {
        Configuration.Bind("AzureAd", options);
        options.UseTokenLifetime = true; // 沿用Azure AD的令牌有效期
        options.SaveTokens = true; // 保存令牌供后续API调用使用
        options.ResponseType = "code"; // 使用授权码流程,和MSAL推荐流程对齐
    });

services.AddAuthorization(options =>
{
    options.FallbackPolicy = options.DefaultPolicy; // 默认要求所有页面认证
});
  • 工作逻辑:用户在Angular端登录后,Azure AD会在浏览器写入ESTSAUTH等SSO cookie。当MVC应用发起认证请求时,Azure AD检测到该cookie,会自动跳过凭证输入步骤,直接返回认证结果,MVC应用据此创建本地登录会话。

方案二:Angular传递授权码给MVC应用(适用于跨域场景)

如果两个应用不在同一域,可通过授权码传递实现无感知登录:

  • Angular端用MSAL获取授权码(注意不要直接传ID令牌,避免泄露风险),导航到MVC的指定回调页面时携带授权码参数;
  • MVC端接收授权码后,向Azure AD令牌端点交换成自身的ID/访问令牌,然后创建本地登录会话:
[HttpGet("signin-from-angular")]
public async Task<IActionResult> SignInFromAngular(string code)
{
    var tokenEndpoint = $"{Configuration["AzureAd:Authority"]}/oauth2/v2.0/token";
    var formData = new Dictionary<string, string>
    {
        ["client_id"] = Configuration["AzureAd:ClientId"],
        ["client_secret"] = Configuration["AzureAd:ClientSecret"],
        ["code"] = code,
        ["redirect_uri"] = Url.Action("SignInFromAngular", "Account", null, Request.Scheme),
        ["grant_type"] = "authorization_code"
    };

    using var client = new HttpClient();
    var response = await client.PostAsync(tokenEndpoint, new FormUrlEncodedContent(formData));
    
    if (!response.IsSuccessStatusCode) return BadRequest("令牌交换失败");
    
    var tokenResponse = await response.Content.ReadFromJsonAsync<TokenResponse>();
    // 构建用户身份并写入Cookie
    var claims = new List<Claim>
    {
        new(ClaimTypes.NameIdentifier, tokenResponse.IdTokenClaims["oid"]),
        new(ClaimTypes.Name, tokenResponse.IdTokenClaims["name"])
    };
    var identity = new ClaimsIdentity(claims, OpenIdConnectDefaults.AuthenticationScheme);
    await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity));
    
    return RedirectToAction("Index", "Home");
}
  • 安全提醒:必须用HTTPS传输,授权码要设置短有效期,同时验证请求来源的合法性,防止CSRF攻击。

方案三:共享认证Cookie(同域/子域场景)

如果两个应用部署在同域或子域下,可配置共享认证Cookie:

  • MVC端配置数据保护和共享Cookie:
services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo(@"c:\shared-keys")) // 两个应用共用密钥存储
    .SetApplicationName("YourSharedAppName"); // 统一应用名称

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.Cookie.Domain = ".yourdomain.com"; // 子域共享时设置根域
        options.Cookie.Name = ".SharedAuthCookie";
    })
    .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"));
  • Angular端配置MSAL使用Cookie存储而非localStorage,确保SSO cookie和应用Cookie兼容:
export const msalConfig: Configuration = {
    auth: {
        clientId: 'your-client-id',
        authority: 'https://login.microsoftonline.com/your-tenant-id',
        redirectUri: 'https://angular.yourdomain.com',
        postLogoutRedirectUri: 'https://angular.yourdomain.com'
    },
    cache: {
        cacheLocation: BrowserCacheLocation.Cookie,
        storeAuthStateInCookie: true
    }
};
  • 工作逻辑:同域下Cookie可跨应用访问,Azure AD的SSO会话结合共享的应用认证Cookie,实现登录状态无缝流转。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 20:40:18