首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ADFS会话到期并导致错误

ADFS会话到期并导致错误
EN

Stack Overflow用户
提问于 2013-03-27 20:27:14
回答 2查看 3.6K关注 0票数 7

我们在内部应用程序中使用ADFS --用户在任何时候都会透明地登录到我们的应用程序中。但是,如果用户打开一个页面超过一个小时,然后尝试在该页面上执行一些操作(除了导航到另一个页面),他们会得到一个错误:

此页面正在访问不在其控制范围内的信息。这构成了安全风险。你想继续吗?

该页面似乎试图将该请求重定向到ADFS服务器,浏览器正在阻止该请求。

因此,我的问题是:如何捕捉这种情况并让用户到ADFS服务器进行重新身份验证?

我还没有在谷歌上找到任何关于这个的运气。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-09-07 15:15:48

您可以在global.asax中手动检查和重新发出安全令牌,并使用它创建滑动会话。使用滑动会话,您可以选择推迟重新身份验证,直到它变得“安全”这样做(当数据将不再丢失由于ADFS重定向)。

在SessionSecurityTokenReceived事件中,您可以计算令牌和请求。如果令牌已过期,并且请求将经历重定向造成的数据丢失,则可以重新发出新的“临时”令牌。新令牌的使用寿命应该非常短,只要足够长,就可以安全地完成当前的请求。然后,令牌将过期,并在下一个请求中再次进行计算。

代码语言:javascript
运行
复制
protected void SessionAuthenticationModule_SessionSecurityTokenReceived(object sender, SessionSecurityTokenReceivedEventArgs e)
{
    var now = DateTime.UtcNow;
    SessionSecurityToken token = e.SessionToken;
    var httpContext = new HttpContextWrapper(this.Context);

   if (now > token.ValidTo
       && (httpContext.Request.IsAjaxRequest() || httpContext.Request.HttpMethod == "POST"))
   {
       var sessionAuthModule = (SessionAuthenticationModule)sender;
       e.SessionToken = sessionAuthModule.CreateSessionSecurityToken(token.ClaimsPrincipal,
                                                                     token.Context,
                                                                     now,
                                                                     now.AddMinutes(2),
                                                                     token.IsPersistent);
       e.ReissueCookie = true;
   }
}

ADFS会话将继续将重新身份验证推迟到下一个GET请求。然后重定向将最终发生,用户将得到一个正常寿命的适当令牌。

票数 1
EN

Stack Overflow用户

发布于 2013-10-08 21:40:56

更新:下面的解决方案取决于iframes。ADFS3.0的X帧选项默认为拒绝,没有更改设置的选项.因此,此解决方案只适用于ADFS2.1和更早的版本。

在您的global.asax.cs中,您将希望捕获任何中间AJAX 302,并将它们转换为401未经授权的。这将阻止调用(并弹出该消息),并将我们发送到$(document).ajaxError()。

代码语言:javascript
运行
复制
    protected void Application_EndRequest()
    {
        var context = new HttpContextWrapper(this.Context);
        if (context.Response.StatusCode == 302 && context.Request.IsAjaxRequest())
        {
            context.Response.Clear();
            context.Response.StatusCode = 401;
        }
    }

然后,在那里,拦截任何401秒,然后再进行其他错误处理。我选择向用户显示一条消息。您可以在这里完成下一步,但是为了可读性,我将ajaxSettings对象发送到另一个函数。返回true,这样它就不会继续您的其他错误处理。

如果您想要检查这是ADFS,event.target.referrer将具有尝试重定向的URL。

代码语言:javascript
运行
复制
$(document).ajaxError(function (event, jqXHR, ajaxSettings, thrownError) {
    if (xhr.status == 401) { 
        alert("Your session has timed out. Click OK to reauthorize and extend your session.");

        TriggerReauthenticationRefresher(ajaxSettings); 
        return true;
    }
…the rest of the error handling code…            
});

针对这种情况,我的页面中有一个空的div,id为‘刷新框’,但是您可以在DOM中的任何元素上这样做。将一个iframe放到您域中的某个虚拟页面上。在我的例子中,ADFSRefresher.cshtml的内容只是

代码语言:javascript
运行
复制
 <div><input type="hidden" value="@DateTime.Now.ToString()" /></div>

我不是使用全局变量,而是使用.data()存储.data()。我们还需要跟踪iframe重新加载多少次,所以我们也在存储负载计数。将iframe插入DOM中,它将启动。

代码语言:javascript
运行
复制
function TriggerReauthenticationRefresher(ajaxSettings) {
    var refreshframe = '<iframe src="@Url.Action("ADFSRefresher", "Debug")" style="display:none" onload="TrackFrameReloads()" />';

    $('#refresherBox').data('loadcount', 0);
    $('#refresherBox').data('originalRequestSettings', ajaxSettings);

    $('#refresherBox').html(refreshframe);
}

TrackFrameReloads将在iframe每次完成加载时开火。因为我们知道有一个即将到来的ADFS重定向,它将发射两次。第一次是重定向,第二次是它的src url。因此,当它第一次启动时,我们只需增加负载计数。

第二次发射时,我们知道我们已经被成功地重新认证了。检索ajaxSettings,清除存储的数据,然后可以重用原始设置来发送AJAX调用!它将通过,不重定向,并运行其原来的成功和完整的功能。

代码语言:javascript
运行
复制
function TrackFrameReloads() {
    var i = $('#refresherBox').data('loadcount');
    if (i == 1) {
        alert('Your session has been extended.');

        var ajaxSettings = $('#refresherBox').data('originalRequestSettings');

        $('#refresherBox').removeData();

        $.ajax(ajaxSettings);

    } else {
        $('#refresherBox').data("loadcount", 1);
    }
}

请注意,如果您定义了它们,错误和完整的函数将已经触发。

如果愿意,可以跳过给用户的两条警告消息。取决于您的ADFS设置,这应该只需1秒,并且用户不需要被告知这一切都发生了!

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15668751

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档