admin管理员组文章数量:1026989
I'm currently working on multiple applications using different frameworks: two ASP.NET MVC applications on legacy .NET, and one ASP.NET Core MVC application. All of these applications use Azure AD B2C for authentication. Both .NET Framework applications implement Azure AD B2C using the OpenID Connect middleware, and they successfully share a single sign-on (SSO) experience.
However, I'm struggling to implement a consistent sign-out experience across these applications.
Specific Issues:
Single Sign-Out Issue:
The sign-out functionality in my ASP.NET Core application works correctly when used on its own. However, logging out from the ASP.NET Core application does not sign out the user from the .NET Framework applications, breaking the consistent single sign-out experience. This issue persists despite all applications using the same Azure AD B2C tenant and policies..NET Framework Logout Implementation:
In my ASP.NET MVC applications, I am usingRequest.GetOwinContext().Authentication.SignOut()
to sign the user out and redirect them to the Azure AD B2C logout URL. While the URL is correct and redirection occurs as expected, it does not successfully sign the user out from the ASP.NET Core application.
What I've tried:
Ensured that the logout URL used in the applications is configured correctly
Double-checked the implementation of the sign-out logic, but the SSO experience remains inconsistent
Implemented front-channel logout as recommended by Microsoft documentation, but this did not resolve the issue
ASP.NET Core MVC application's code:
builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration,Microsoft.Identity.Web.Constants.AzureAdB2C);
builder.Services.Configure<CookieAuthenticationOptions>(options =>
{
options.SlidingExpiration = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
});
builder.Services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.SignedOutCallbackPath = new PathString("/signout-callback-oidc");
options.Events.OnRedirectToIdentityProviderForSignOut = context =>
{
var id_token_hint = context.Properties.Items.FirstOrDefault(x => x.Key == "id_token_hint").Value;
if (id_token_hint != null)
{
context.ProtocolMessage.SetParameter("id_token_hint", id_token_hint);
}
return Task.CompletedTask;
};
options.Events.OnAuthenticationFailed = context =>
{
context.HandleResponse();
context.Response.Redirect("/Error/ErrorMessage?message=" + context.Exception.Message);
return Task.CompletedTask;
};
});
ASP.NET MVC application:
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
var env = (baseEnv.ToLower() == "live") ? "" : baseEnv;
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies",
CookieSecure = CookieSecureOption.Always,
CookieHttpOnly = true,
CookiePath = "/",
ExpireTimeSpan = new TimeSpan(28,0,0,0,0),
SlidingExpiration = true
});
var baseUrlCleansed = $"{baseUrl.TrimEnd('/')}";
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
MetadataAddress = "https://" + tenantName + ".b2clogin/" + tenantName + ".onmicrosoft/" + signinFlow + "/v2.0/.well-known/openid-configuration",
ClientId = clientId,
RedirectUri = $"{baseUrlCleansed}/",
ResponseType = "id_token",
PostLogoutRedirectUri = $"{baseUrlCleansed}/",
Scope = "openid",
SignInAsAuthenticationType = "Cookies",
UseTokenLifetime = false,
Notifications = new OpenIdConnectAuthenticationNotifications
{
SecurityTokenValidated = async n =>
{
var id = n.AuthenticationTicket.Identity;
id.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));
var claimsProcessor = new ClaimsProcessor();
await claimsProcessor.ProcessClaims(id);
},
RedirectToIdentityProvider = n =>
{
if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
{
var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");
if (idTokenHint != null)
{
n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
}
}
return Task.FromResult(0);
},
AuthenticationFailed = n =>
{
var exception = n.Exception;
if (exception is OpenIdConnectProtocolInvalidNonceException && exception.Message.Contains("IDX10316"))
{
n.HandleResponse();
n.Response.Redirect("/");
}
if (exception.Message.StartsWith("OICE_20004") || exception.Message.Contains("IDX10311"))
{
n.SkipToNextMiddleware();
n.Response.Redirect("/");
}
return Task.FromResult<object>(null);
},
MessageReceived = n =>
{
return Task.FromResult<object>(null);
}
}
});
I'm currently working on multiple applications using different frameworks: two ASP.NET MVC applications on legacy .NET, and one ASP.NET Core MVC application. All of these applications use Azure AD B2C for authentication. Both .NET Framework applications implement Azure AD B2C using the OpenID Connect middleware, and they successfully share a single sign-on (SSO) experience.
However, I'm struggling to implement a consistent sign-out experience across these applications.
Specific Issues:
Single Sign-Out Issue:
The sign-out functionality in my ASP.NET Core application works correctly when used on its own. However, logging out from the ASP.NET Core application does not sign out the user from the .NET Framework applications, breaking the consistent single sign-out experience. This issue persists despite all applications using the same Azure AD B2C tenant and policies..NET Framework Logout Implementation:
In my ASP.NET MVC applications, I am usingRequest.GetOwinContext().Authentication.SignOut()
to sign the user out and redirect them to the Azure AD B2C logout URL. While the URL is correct and redirection occurs as expected, it does not successfully sign the user out from the ASP.NET Core application.
What I've tried:
Ensured that the logout URL used in the applications is configured correctly
Double-checked the implementation of the sign-out logic, but the SSO experience remains inconsistent
Implemented front-channel logout as recommended by Microsoft documentation, but this did not resolve the issue
ASP.NET Core MVC application's code:
builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration,Microsoft.Identity.Web.Constants.AzureAdB2C);
builder.Services.Configure<CookieAuthenticationOptions>(options =>
{
options.SlidingExpiration = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
});
builder.Services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.SignedOutCallbackPath = new PathString("/signout-callback-oidc");
options.Events.OnRedirectToIdentityProviderForSignOut = context =>
{
var id_token_hint = context.Properties.Items.FirstOrDefault(x => x.Key == "id_token_hint").Value;
if (id_token_hint != null)
{
context.ProtocolMessage.SetParameter("id_token_hint", id_token_hint);
}
return Task.CompletedTask;
};
options.Events.OnAuthenticationFailed = context =>
{
context.HandleResponse();
context.Response.Redirect("/Error/ErrorMessage?message=" + context.Exception.Message);
return Task.CompletedTask;
};
});
ASP.NET MVC application:
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
var env = (baseEnv.ToLower() == "live") ? "" : baseEnv;
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies",
CookieSecure = CookieSecureOption.Always,
CookieHttpOnly = true,
CookiePath = "/",
ExpireTimeSpan = new TimeSpan(28,0,0,0,0),
SlidingExpiration = true
});
var baseUrlCleansed = $"{baseUrl.TrimEnd('/')}";
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
MetadataAddress = "https://" + tenantName + ".b2clogin/" + tenantName + ".onmicrosoft/" + signinFlow + "/v2.0/.well-known/openid-configuration",
ClientId = clientId,
RedirectUri = $"{baseUrlCleansed}/",
ResponseType = "id_token",
PostLogoutRedirectUri = $"{baseUrlCleansed}/",
Scope = "openid",
SignInAsAuthenticationType = "Cookies",
UseTokenLifetime = false,
Notifications = new OpenIdConnectAuthenticationNotifications
{
SecurityTokenValidated = async n =>
{
var id = n.AuthenticationTicket.Identity;
id.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));
var claimsProcessor = new ClaimsProcessor();
await claimsProcessor.ProcessClaims(id);
},
RedirectToIdentityProvider = n =>
{
if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
{
var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");
if (idTokenHint != null)
{
n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
}
}
return Task.FromResult(0);
},
AuthenticationFailed = n =>
{
var exception = n.Exception;
if (exception is OpenIdConnectProtocolInvalidNonceException && exception.Message.Contains("IDX10316"))
{
n.HandleResponse();
n.Response.Redirect("/");
}
if (exception.Message.StartsWith("OICE_20004") || exception.Message.Contains("IDX10311"))
{
n.SkipToNextMiddleware();
n.Response.Redirect("/");
}
return Task.FromResult<object>(null);
},
MessageReceived = n =>
{
return Task.FromResult<object>(null);
}
}
});
本文标签: cAzure B2C Logout Implementation in ASPNET Core MVC and ASPNET MVC applicationsStack Overflow
版权声明:本文标题:c# - Azure B2C Logout Implementation in ASP.NET Core MVC and ASP.NET MVC applications - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745656330a2161618.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论