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

Azure托管ASP.NET MVC应用实现SSO单点登录故障排查

问题定位

你遇到的SSO失效由两个核心问题共同导致:

  1. 本地开发环境有C:\ApplicationData目录的读写权限,数据保护密钥可以正常持久化,两个应用读取同一份密钥实现Cookie互信;但Azure App Service运行在沙箱环境中,默认无C盘非系统目录的读写权限,会抛出Access Denied错误,两个应用各自生成独立的临时密钥,无法解密对方签发的认证Cookie。
  2. 你配置的CookieDomain = ".azurewebsites.net"在生产环境完全无效:azurewebsites.net属于公共后缀列表(Public Suffix List)收录的域名,现代浏览器(Chrome/Edge/Firefox等)会主动拒绝给该根域设置跨子域Cookie,根本不会在两个应用的域名间传递认证Cookie。

另外你现有配置还有一处逻辑不一致:Cookie认证选项里配置的过期时间是120分钟,但登录逻辑里手动设置的Cookie过期时间是30分钟,会导致实际Cookie有效期和预期不符,不影响SSO生效但建议统一。

修复方案

按以下步骤调整配置即可实现Azure环境下的跨应用SSO:

1. 替换密钥存储方案(必须)

不要使用本地磁盘路径存储数据保护密钥,生产环境推荐使用Azure Blob Storage持久化密钥环、Azure Key Vault加密密钥,两个应用共用同一份存储和密钥即可实现Cookie互信。

  • 首先为两个应用安装所需NuGet包:
Install-Package Microsoft.Owin.Security.Interop
Install-Package Microsoft.AspNetCore.DataProtection.AzureStorage
Install-Package Microsoft.AspNetCore.DataProtection.AzureKeyVault
Install-Package Microsoft.Azure.Services.AppAuthentication
  • 提前准备资源:
    • 新建一个Azure Storage账户,在其中创建一个私有Blob容器用于存储密钥文件
    • 新建Azure Key Vault,为两个App Service开启系统托管标识,并授予托管标识对Key Vault中密钥的Get、Wrap、Unwrap权限,对Storage账户Blob容器的Storage Blob Data Contributor权限
  • 替换Startup.Auth.cs中原有DataProtection初始化逻辑,修正后的完整Cookie认证配置如下:
public void ConfigureAuth(IAppBuilder app)
{
    app.CreatePerOwinContext(ApplicationDbContext.Create);
    app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
    app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

    // 初始化共享数据保护提供器
    var blobUri = new Uri("https://<你的存储账户名>.blob.core.windows.net/<密钥容器名>/auth-keys.xml");
    var keyVaultKeyIdentifier = "https://<你的Key Vault名称>.vault.azure.net/keys/<加密密钥名>/";
    var tokenProvider = new AzureServiceTokenProvider();
    var dataProtectionProvider = DataProtectionProvider.Create(
        new AzureBlobStorageRepository(new CloudBlockBlob(blobUri)),
        builder =>
        {
            builder.SetApplicationName("SharedCookieApp");
            // 测试环境可删除下一行,仅用Blob存储密钥即可运行,生产环境建议保留
            builder.ProtectKeysWithAzureKeyVault(
                new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(tokenProvider.KeyVaultTokenCallback)),
                keyVaultKeyIdentifier);
        }
    );

    app.UseCookieAuthentication(new CookieAuthenticationOptions()
    {
        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
        CookieName = ".AspNet.SharedCookie",
        CookieDomain = ".<你的自定义根域>",
        SlidingExpiration = true,
        ExpireTimeSpan = TimeSpan.FromMinutes(120),
        LoginPath = PathString.FromUriComponent("/Account/Login"),
        LogoutPath = PathString.FromUriComponent("/Account/Logout"),
        TicketDataFormat = new AspNetTicketDataFormat(
            new DataProtectorShim(
                dataProtectionProvider.CreateProtector(
                    "Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware",
                    "Cookies.Application",
                    "v2"
                )
            )
        ),
        CookieManager = new ChunkingCookieManager(),
        CookieSecure = CookieSecureOption.Always // 生产环境强制HTTPS传输Cookie,避免被窃听
    });
}

注意:两个应用的上述配置必须完全一致,包括ApplicationName、CreateProtector传入的字符串序列、Cookie名称、域名等所有参数,任意参数不一致都会导致解密失败。

2. 配置自定义域名(必须)

由于.azurewebsites.net的公共后缀限制,你必须为两个应用绑定同一个根域下的自定义子域名,例如app1.yourdomain.com、app2.yourdomain.com,将配置中的CookieDomain值改为.yourdomain.com,同时为两个自定义域名开启HTTPS。配置完成后浏览器才会正常在两个子域间传递认证Cookie。

3. 统一登录逻辑的Cookie过期时间

将登录逻辑中手动设置的ExpiresUtc和Cookie认证配置中的ExpireTimeSpan保持一致,避免出现Cookie提前过期的问题:

authenticationManager.SignIn(new AuthenticationProperties()
{
    AllowRefresh = true,
    IsPersistent = true,
    ExpiresUtc = DateTime.UtcNow.AddMinutes(120),
    IssuedUtc = DateTime.UtcNow
}, id);
验证步骤

发布应用后按以下顺序验证:

  1. 访问第一个应用完成登录,打开浏览器开发者工具-应用-Cookies,确认存在.AspNet.SharedCookieCookie,域名为你配置的自定义根域,没有关联azurewebsites.net域名
  2. 直接访问第二个应用的需要登录的页面,确认无需跳转登录页即可正常访问,请求头中自动携带了共享认证Cookie
  3. 若需要单点登出能力,可在任意一个应用的退出逻辑中,调用另一个应用的登出接口清除Cookie即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 08:06:19