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

Azure B2C登出后仍保持认证状态的问题求助

Azure B2C登出后仍保持认证状态的问题

我基于.NET 4.8开发ASP.NET MVC应用并集成Azure B2C,采用Cookie认证和自定义流策略的本地用户账户,登录流程正常。但遇到登出问题:本地测试时,用户点击“Sign Out”按钮后,已清除本地数据并按文档指引跳转至B2C登出链接,跳转看似成功,但点击浏览器返回按钮、打开新标签页或重新访问页面(甚至打开新浏览器)时,用户仍处于B2C认证状态。

相关代码

Startup中的登录配置

public void ConfigureAuth(IAppBuilder app)
{
    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        // ASP.NET web host compatible cookie manager
        CookieManager = new SystemWebChunkingCookieManager(),
        CookieName = "MyPortal.AuthCookie",
        CookieSameSite = Microsoft.Owin.SameSiteMode.Lax,
        CookieSecure = CookieSecureOption.Always,
        CookieHttpOnly = true,
        CookiePath = Globals.ApplicationRelativePath
    });

    app.UseOpenIdConnectAuthentication(
        new OpenIdConnectAuthenticationOptions
        {
            // Generate the metadata address using the tenant and policy information
            MetadataAddress = String.Format(Globals.WellKnownMetadata, Globals.TenantId, Globals.DefaultPolicy),

            // These are standard OpenID Connect parameters, with values pulled from web.config
            ClientId = Globals.ClientId,
            RedirectUri = Globals.RedirectUri,
            PostLogoutRedirectUri = Globals.PostLogoutRedirectUri,
            UseTokenLifetime = true,

            // Add the ProtocolValidator property here
            // Specify the callbacks for each type of notifications
            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                RedirectToIdentityProvider = OnRedirectToIdentityProvider,
                AuthenticationFailed = OnAuthenticationFailed,
                SecurityTokenValidated = OnSecurityTokenValidated
            },

            // Specify the claim type that specifies the Name property.
            TokenValidationParameters = new TokenValidationParameters
            {
                NameClaimType = "name",
                RoleClaimType = "extension_Role",
                ValidateIssuer = false
            },

            // Specify the scope by appending all of the scopes requested into one string (separated by a blank space)
            Scope = $"openid profile offline_access {Globals.ReadTasksScope} {Globals.WriteTasksScope}",

            // ASP.NET web host compatible cookie manager
            CookieManager = new SystemWebCookieManager(),
        }
    );
}

登出函数

public ActionResult LogOff()
{
    // Log out through OWIN 
    IEnumerable<AuthenticationDescription> authTypes = HttpContext.GetOwinContext().Authentication.GetAuthenticationTypes();
    HttpContext.GetOwinContext().Authentication.SignOut(authTypes.Select(t => t.AuthenticationType).ToArray());

    Request.GetOwinContext().Authentication.GetAuthenticationTypes();
    HttpContext.User = new GenericPrincipal(new GenericIdentity(string.Empty), null);

    // Expire cookie
    if (Request.Cookies["MyPortal.AuthCookie"] != null)
    {
        HttpCookie authCookie = new HttpCookie("MyPortal.AuthCookie");
        authCookie.Expires = DateTime.Now.AddDays(-1d);
        Response.Cookies.Add(authCookie);
    }

    try
    {
        AccountManager accountManager = new AccountManager();
        accountManager.LogOff();

        var RequestUri = new System.Uri(Globals.AadLogoutUrl);
        return Redirect(RequestUri.ToString());
    }
    catch
    {
        throw;
    }
}

登出请求URI

https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{flow}/oauth2/v2.0/logout?post_logout_redirect_uri={redirectURI}

问题分析与解决方案

当前登出方式的问题

  1. 未触发OpenID Connect全局登出流程:直接跳转B2C登出URL,但未通过OWIN的OpenID Connect中间件发起登出请求,导致B2C端的会话Cookie未被完全清除。
  2. 手动操作Cookie冗余无效:OWIN的SignOut方法已自动处理应用端Cookie清除,手动过期Cookie的操作可能因上下文问题失效,属于冗余操作。
  3. 登出URL配置不严谨:post_logout_redirect_uri需确保已在Azure B2C应用注册中添加为允许的重定向URI,且需正确编码。

修正后的实现步骤

1. 优化LogOff方法

直接通过OWIN中间件触发全局登出,无需手动处理Cookie和用户身份:

public ActionResult LogOff()
{
    var authProperties = new AuthenticationProperties
    {
        RedirectUri = Globals.PostLogoutRedirectUri
    };
    
    // 明确指定登出Cookie认证和OpenID Connect认证类型
    HttpContext.GetOwinContext().Authentication.SignOut(authProperties, 
        CookieAuthenticationDefaults.AuthenticationType, 
        OpenIdConnectAuthenticationDefaults.AuthenticationType);

    return new EmptyResult();
}

2. 配置RedirectToIdentityProvider通知

在登出时确保携带正确的B2C策略和重定向URI:

private Task OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
{
    if (notification.ProtocolMessage.RequestType == OpenIdConnectRequestType.Logout)
    {
        // 替换为自定义策略名称
        notification.ProtocolMessage.IssuerAddress = notification.ProtocolMessage.IssuerAddress.Replace("{flow}", Globals.DefaultPolicy);
        // 确保重定向URI正确设置
        notification.ProtocolMessage.PostLogoutRedirectUri = Globals.PostLogoutRedirectUri;
    }
    return Task.FromResult(0);
}

3. 验证Azure B2C配置

  • 确认PostLogoutRedirectUri已添加到Azure B2C应用注册的注销URL列表中,且与代码中的值完全一致(包括协议、域名、路径)。
  • 检查自定义策略的登出流程配置,确保全局会话能被正常清除。

4. 测试注意事项

  • 本地测试需使用HTTPS,因为CookieSecure = CookieSecureOption.Always会导致HTTP环境下Cookie无法正常传递,引发状态异常。
  • 测试前清除浏览器缓存和Cookie,避免旧会话残留影响结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 11:32:03