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

如何在iframe中使用Azure AD与OpenID Connect实现SSO

在iframe中嵌入受OpenID Connect SSO保护的Web应用问题

我花了好几个小时寻找在iframe里调用受OpenID Connect SSO保护的Web应用的方法,当前状态:

  • 通过iframe访问时,要么跳转到https://localhost:5001/signin-oidc,要么出现指向https://localhost:5001的错误
  • 直接用浏览器访问该应用能正常显示Azure登录界面,但就算先登录再通过iframe访问仍无法正常工作

应用B的配置详情

  • 基于Rider默认模板创建
  • csproj配置片段:
...
<UserSecretsId>SomeGuideWithName</UserSecretsId>
<WebProject_DirectoryAccessLevelKey>0</WebProject_DirectoryAccessLevelKey>
...
  • App.razor配置:
<CascadingAuthenticationState>
    <Router AppAssembly="@typeof(App).Assembly">
        <Found Context="routeData">
            <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"/>
            <FocusOnNavigate RouteData="@routeData" Selector="h1"/>
        </Found>
        <NotFound>
            <PageTitle>Not found</PageTitle>
            <LayoutView Layout="@typeof(MainLayout)">
                <p role="alert">Sorry, there's nothing at this address.</p>
            </LayoutView>
        </NotFound>
    </Router>
</CascadingAuthenticationState>
  • appsettings.json配置:
"AzureAd": {
  "Instance": "https://login.microsoftonline.com/",
  "Domain": "xxx.onmicrosoft.com",
  "TenantId": "xxx",
  "ClientId": "xxx",
  "CallbackPath": "/signin-oidc"
}
  • Program.cs配置:
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.UI;
using MitAuth.Data;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddControllersWithViews()
    .AddMicrosoftIdentityUI();

builder.Services.AddAuthorization(
    options =>
    {
        // By default, all incoming requests will be authorized according to the default policy
        options.FallbackPolicy = options.DefaultPolicy;
    }
);

builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor()
    .AddMicrosoftIdentityConsentHandler();
builder.Services.AddSingleton<WeatherForecastService>();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();

app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

app.Run();
  • 生成的Cookies如图所示

咨询问题

  1. 是否需要重新配置应用B?
  2. 应用A是否需要进行额外操作?
  3. 是否需要传递令牌或类似内容?

解决方案

1. 应用B的必要配置调整

(1)修改认证Cookie的SameSite属性

默认情况下ASP.NET Core的认证Cookie为SameSite=Lax,这种模式下Cookie不会在跨域iframe请求中发送,导致应用B无法识别已登录状态。需将其设置为None(必须配合HTTPS使用,因为SameSite=None要求Cookie带Secure属性):

builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
    .AddCookie(options =>
    {
        options.Cookie.SameSite = SameSiteMode.None;
        options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
        options.Cookie.IsEssential = true;
    });

(2)配置CORS允许应用A域名

应用B需要允许来自应用A的跨域请求,在Program.cs中添加CORS配置:

builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowAppA", policy =>
    {
        policy.WithOrigins("https://app-a-domain.com") // 替换为应用A的实际域名
              .AllowAnyHeader()
              .AllowAnyMethod()
              .AllowCredentials();
    });
});

// 在app.UseRouting()之后添加
app.UseCors("AllowAppA");

(3)配置iframe嵌入权限

默认HSTS会添加X-Frame-Options: DENY头阻止嵌入,推荐用Content-Security-Policy精确控制允许嵌入的域名:

app.Use(async (context, next) =>
{
    context.Response.Headers.Add("Content-Security-Policy", "frame-ancestors 'self' https://app-a-domain.com");
    await next();
});

2. 应用A的操作

应用A只需确保:

  • 嵌入iframe的URL为应用B的正确地址
  • 自身运行在HTTPS环境下(因为SameSite=None要求Cookie通过HTTPS传输,跨域iframe请求必须用HTTPS)
    无需额外复杂操作。

3. 令牌传递相关

不需要手动传递令牌。应用B基于Cookie认证,只要Cookie配置正确,浏览器会自动在iframe请求中携带认证Cookie,应用B即可识别登录状态。如果后续需要跨应用共享身份,可考虑OAuth2令牌交换,但当前场景无需此操作。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 05:20:29