在Owin的OnAuthenticationFailed中获取原始请求URL的方法咨询
解决方案:在OnAuthenticationFailed中获取原始请求URL
你的问题核心是OIDC认证流程属于跨请求跳转,初始请求的Owin上下文在回调时已丢失,所以之前存的环境变量无法读取。下面提供两个可行的方案:
方案1:通过AuthenticationProperties传递原始URL
在触发Challenge时,把当前页面URL存入AuthenticationProperties的自定义字典中,回调失败时从这里读取:
触发Challenge的代码:
var authProps = new AuthenticationProperties { Dictionary = { { "OriginalPageUrl", HttpContext.Current.Request.RawUrl } } }; HttpContext.Current.GetOwinContext().Authentication.Challenge(authProps, OpenIdConnectAuthenticationDefaults.AuthenticationType);
在OnAuthenticationFailed中处理:
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions { // 其他Okta相关配置(ClientId、Authority等) OnAuthenticationFailed = context => { // 尝试从Properties中取出原始URL if (context.Properties.Dictionary.TryGetValue("OriginalPageUrl", out var rawUrlObj) && rawUrlObj is string originalUrl) { // 判断是否是目标公共页面,比如"/PublicHome.aspx" if (originalUrl.Equals("/PublicHome.aspx", StringComparison.OrdinalIgnoreCase)) { // 取消默认的错误重定向 context.HandleResponse(); // 重定向回公共页面,保持未认证状态 context.Response.Redirect(originalUrl); return Task.CompletedTask; } } // 非公共页面的认证失败,走原有错误重定向逻辑 context.Response.Redirect("/AuthError.aspx"); return Task.CompletedTask; } });
方案2:用临时Cookie存储原始URL
如果不想修改Challenge的调用代码,可以在触发Challenge前把URL存到临时Cookie,回调失败时读取并删除:
触发Challenge前的Cookie设置:
// 存临时Cookie,设置短过期时间避免残留 var tempCookie = new HttpCookie("TempOriginalUrl") { Value = HttpContext.Current.Request.RawUrl, HttpOnly = true, Expires = DateTime.UtcNow.AddMinutes(5) }; HttpContext.Current.Response.Cookies.Add(tempCookie); // 触发认证挑战 HttpContext.Current.GetOwinContext().Authentication.Challenge(OpenIdConnectAuthenticationDefaults.AuthenticationType);
在OnAuthenticationFailed中处理:
OnAuthenticationFailed = context => { var tempCookie = context.Request.Cookies["TempOriginalUrl"]; if (tempCookie != null) { var originalUrl = tempCookie.Value; // 立即删除临时Cookie context.Response.Cookies.Delete("TempOriginalUrl"); if (originalUrl.Equals("/PublicHome.aspx", StringComparison.OrdinalIgnoreCase)) { context.HandleResponse(); context.Response.Redirect(originalUrl); return Task.CompletedTask; } } // 其他情况走错误页 context.Response.Redirect("/AuthError.aspx"); return Task.CompletedTask; }
为什么之前的中间件方法无效?
OIDC认证是跨请求流程:用户访问公共页面→触发Challenge→重定向到Okta→Okta回调回你的应用。回调请求是一个全新的Owin上下文,和初始请求的上下文完全独立,所以你在初始请求中存入环境变量的值,在回调请求的OnAuthenticationFailed里根本取不到。
内容的提问来源于stack exchange,提问作者user464291
相关产品推荐
相关产品推荐

