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

在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 21:47:21