7

内部アプリケーションには ADFS を使用しています。ユーザーは基本的に、いずれかのアプリにアクセスするたびに透過的にログインします。ただし、ユーザーが 1 時間以上ページを開いたままにし、そのページで何か (別のページに移動する以外) を行おうとすると、次のエラーが発生します。

このページは、その管理下にない情報にアクセスしています。これは、セキュリティ上のリスクをもたらします。続けたいですか?

ページがその要求を ADFS サーバーにリダイレクトしようとしているように見えますが、それはブラウザーによって阻止されています。

したがって、私の質問は次のとおりです。この状況をキャッチして、ユーザーを ADFS サーバーにアクセスさせて再認証するにはどうすればよいですか?

これに関してGoogleで何かを見つけることができませんでした。

4

2 に答える 2

3

更新: 以下の解決策は iframe に依存します。ADFS 3.0 の X-Frame-Options はデフォルトで DENY に設定されており、設定を変更するオプションはありません。したがって、このソリューションは ADFS 2.1 以前でのみ機能します。

global.asax.cs で、中間の AJAX 302 をキャッチし、それらを 401 Unauthorized に変換する必要があります。これにより、呼び出しが続行されなくなり (そしてそのメッセージがポップされ)、$(document).ajaxError() に送信されます。

    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 があります。

$(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…            
});

この状況のた​​めだけに、ページに「refresherBox」の ID を持つ空の div がありますが、DOM の任意の要素でこれを行うことができます。ドメイン内のダミー ページに移動する iframe をまとめます。私の場合、 ADFSRefresher.cshtml の内容は

 <div><input type="hidden" value="@DateTime.Now.ToString()" /></div>

グローバル変数を使用する代わりに、.data() を使用して ajaxSettings を保存しています。iframe のリロード回数も追跡する必要があるため、loadcount も保存しています。iframe を DOM に挿入すると、開始されます。

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 リダイレクトがあることがわかっているため、2 回発生します。1 回目はリダイレクト、2 回目はその src URL へのリダイレクトです。したがって、最初に起動したときは、loadcount をインクリメントするだけです。

2 回目の起動で、再認証に成功したことがわかります。ajaxSettings を取得し、保存されているデータを消去すると、元の設定を再利用して AJAX 呼び出しを送信できます。リダイレクトされずに通過し、元の成功と完全な機能を実行します。

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);
    }
}

それらを定義した場合、エラーおよび完全な関数はすでに起動されていることに注意してください。

必要に応じて、ユーザーへの 2 つの警告メッセージをスキップできます。ADFS の設定にもよりますが、これには 1 秒しかかからず、ユーザーにこれが発生したことを通知する必要はまったくありません。

于 2013-10-08T21:40:56.580 に答える
1

global.asax でセキュリティ トークンを手動で検査および再発行し、これを使用してスライディング セッションを作成できます。スライディング セッションでは、「安全」になるまで (ADFS リダイレクトによってデータが失われなくなるまで) 再認証を延期することを選択できます。

SessionSecurityTokenReceived イベント内で、トークンとリクエストを評価できます。トークンの有効期限が切れていて、リクエストがリダイレクトによってデータが失われる可能性がある場合は、新しい「一時的な」トークンを再発行できます。新しいトークンの有効期間は非常に短く、現在のリクエストを安全に完了するのに十分な長さでなければなりません。その後、トークンは期限切れになり、次のリクエストで再度評価されます。

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 要求まで再認証を延期し続けます。その後、リダイレクトが最終的に発生し、ユーザーには通常の有効期間の適切なトークンが発行されます。

于 2016-09-07T15:15:48.850 に答える