Azure B2C令牌过期触发AntiforgeryException,重定向登录页异常问题
问题解决:令牌过期触发AntiforgeryException后,重定向自定义登录页被自动跳转至Azure AD的处理
背景
基于C# MVC开发的应用,登录页包含两个按钮:
- 内部用户登录:跳转至Azure AD认证流程
- 外部用户登录:跳转至Azure AD认证流程
外部用户登录后闲置30分钟(Azure B2C访问令牌过期),操作时触发AntiforgeryException,尝试重定向到自定义登录页,但页面渲染后会进入Startup.cs的AuthorizeCore方法,最终自动跳转到Azure AD流程,而非显示带两个按钮的自定义登录页。
原因分析
虽然为LogInController和Index操作添加了[AllowAnonymous]特性,但全局授权逻辑或RedirectToIdentityProvider事件会在未认证用户访问时,自动触发跳转至Azure AD身份提供者,没有区分用户是主动访问登录页还是因异常重定向而来的场景。
解决方案
1. 修改AntiforgeryException重定向逻辑,添加标识参数
在异常处理代码中,给重定向请求添加一个标识参数,用于后续判断是否需要停留在自定义登录页:
if (filterContext.Exception is HttpAntiForgeryException) { var routeData = new RouteValueDictionary(new { controller = "LogIn", action = "Index", returnToLoginPage = true // 添加标识,说明是从防伪造错误跳转而来 }); filterContext.ExceptionHandled = true; filterContext.Result = new RedirectToRouteResult(routeData); }
2. 在RedirectToIdentityProvider事件中添加判断,跳过自动跳转
在Startup.cs的OpenIdConnect配置中,修改RedirectToIdentityProvider事件,检查当前请求是否指向自定义登录页,若是则取消自动跳转:
services.Configure<OpenIdConnectOptions>(AzureADB2CDefaults.OpenIdScheme, options => { // 保留原有配置... options.Events = new OpenIdConnectEvents { RedirectToIdentityProvider = context => { // 检查请求路径是否为自定义登录页,或带有标识参数 var requestPath = context.HttpContext.Request.Path; var queryParams = context.HttpContext.Request.Query; if (requestPath.StartsWithSegments("/LogIn/Index") || queryParams.ContainsKey("returnToLoginPage")) { // 手动重定向到自定义登录页,并终止后续身份提供者跳转逻辑 context.Response.Redirect("/LogIn/Index"); context.HandleResponse(); } return Task.CompletedTask; }, // 保留其他事件配置... }; });
3. 确保自定义登录页完全绕过全局授权
如果项目中配置了全局[Authorize]过滤器,需确保LogInController的操作被[AllowAnonymous]完全覆盖:
[AllowAnonymous] public class LogInController : Controller { public IActionResult Index() { return View(); } // 其他登录相关操作也需添加[AllowAnonymous] }
或者在全局授权配置中直接排除LogIn控制器:
services.AddMvc(options => { var authPolicy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .Build(); options.Filters.Add(new AuthorizeFilter(authPolicy)); // 排除LogIn控制器,允许匿名访问 options.Filters.Add(new AllowAnonymousFilter { Controller = typeof(LogInController) }); }) .AddControllersAsViews();
原理说明
通过添加标识参数和事件判断,我们可以区分用户是主动访问登录页,还是因令牌过期/防伪造错误被重定向的场景,从而避免全局授权逻辑自动触发Azure AD跳转,让用户停留在自定义登录页选择登录方式。
内容的提问来源于stack exchange,提问作者user3387302
相关产品推荐
相关产品推荐

