4

サービスを呼び出しています。リクエストするたびに、ユーザーの永続的なセキュリティトークンを渡す必要があります。

これを行うために、このメソッドを基本コントローラークラスに追加しました。

protected UserData getUsr()
{
        try
        {
            UserData usr = new UserData();
            usr.SecurityToken = Session["secToken"].ToString();

            MembershipUser mvcUser = Membership.GetUser(HttpContext.User.Identity.Name);
            usr.Id = (int)mvcUser.ProviderUserKey;

            return usr;
        }
        catch (Exception ex)
        {
            log.Debug("Could not create usr object", ex);
            throw new Exception("Could not authenticate");
        }
    }

ここでのこの問題は、User.Identityデータがセッションデータよりも長持ちすることがあり、ユーザーがログインしていることを確認してもリクエストが失敗するという奇妙なバグが発生することです。

このトークンを保存するためのより良い方法はありますか/User.Identityオブジェクトが期限切れになるたびに期限切れになるように保存できますか?

また、HttpContextとMVCの基本的な理解の例/ドキュメントを知っている人がいれば、それは素晴らしいフィルターを承認します。

4

4 に答える 4

5

ユーザーのセキュリティトークンをフォーム認証Cookie自体に保存するために行きます。このFormsAuthenticationTicketクラスにUserDataは、追加情報を含めることができるプロパティが含まれています。

プロパティで指定された値UserDataは、認証チケットCookieの一部として含まれ、他のチケットフィールドと同様に、フォーム認証システムの構成に基づいて暗号化および検証されます。

これは、フォーム認証Cookieに追加情報を保存する方法を説明した記事です。

これは、フォームauthに追加データを保存することについて多くを説明する大きな記事です。クッキーとその読み方。コードはVBで記述されており、適切にフォーマットされていません。ステップ4:追加のユーザーデータをチケットに保存するまで下にスクロールする必要があります。

このスレッドUserDataでは、Cookieからを読み取る方法について簡単に回答します。

ここValueProviderで説明するような、認証からセキュリティトークンを読み取るカスタムを作成します。cookieとアクションパラメータへのフィード。

于 2012-11-06T09:47:39.983 に答える
1

ユーザーのセキュリティトークン、IPアドレス、およびタイムスタンプを文字列に配置できます。AESなどの対称アルゴリズムを使用して文字列を暗号化し、Cookieとして配置します。次に、Cookieから読み取るようにコードを変更します。Cookie内のIPアドレスがユーザーのIPアドレスと一致することを検証できます。これにより、誰かがCookieの値を盗んで再生するのを防ぐことができます。 ここはAESに関するMSDNドキュメントです(Rjindaelは元の名前です)。このスキームでは、Cookieが期限切れになるか、タイムアウトに達するまで、トークンは期限切れになりません。タイムアウトを設定し、永久または永続的にしないことを強くお勧めします。タイムアウトを除外すると、スキームの安全性が低下します。また、Cookie値の先頭にタイムスタンプを付けます。これらのアルゴリズムのCBCモードにより、先頭のビットが変更されるため、暗号化された文字列の外観に影響します(アバランチ効果)。

ASP.NETメンバーシッププロバイダーにも認証Cookieがあるため、このCookieはメンバーシップCookieの前に期限切れにならないようにする必要があります。HTTPはステートレスであるのに対し、Cookieはユーザーの制御下にあり、リクエストが行われるたびに渡されるため、ユーザーがまだそこにいるという保証はないため、セッションはタイムアウト時に期限切れになる必要があります。

getUsr関数

protected UserData getUsr()
{
    try
    {
        UserData usr = new UserData();

        string token = Request.Cookies["secToken"].Value;

        // implement RijndaelManaged encryption/decryption scheme
        // this can also be serialized as an object to make cleaner
        var tokenValues = Decrypt(token).Split(',');

        // The timeout expired
        if (DateTime.Now > DateTime.Parse(tokenValues[1]))
        {
            throw new Exception("Timeout");
        }

        // someone stole this cookie or is on a different internet connection
        if (tokenValues[0] != System.Web.HttpContext.Current.Request.UserHostAddress)
        {
            throw new Exception("Invalid IP");
        }

        // You're ok everything checks out
        usr.SecurityToken = tokenValues[3].ToString();

        MembershipUser mvcUser = Membership.GetUser(HttpContext.Current.User.Identity.Name);
        usr.Id = (int)mvcUser.ProviderUserKey;

        return usr;
    }
    catch (Exception ex)
    {
        log.Debug("Could not create usr object", ex);
        throw new Exception("Could not authenticate");
    }
}
于 2012-11-03T14:47:54.740 に答える
1

私が言っていることは非常に愚かかもしれませんが、以前は同様の問題があり、セッションの有効期限をログインした有効期限よりも長く設定するだけで解決しました。いつでも、セッションデータを更新するセキュリティトークンを使用してWebサイトにアクセスできるため、ユーザーがログインしている間、セキュリティトークンが確実に持続します。セッションの継続時間が長いという事実は、問題を引き起こすことはありません。ログインしたユーザーだけがそのデータを使用でき、新しいユーザーがログインすると、古いセッションエントリが置き換えられます。

于 2012-11-04T12:14:50.037 に答える
0

User.Identityセッションより長持ちする場合は、トークンをClaimIDにとして保存してみませんか?何かのようなもの:

var claims = new[]
{
    new Claim("access_token", string.Format("Bearer {0}", token)),
};

var identity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);

Request.GetOwinContext().Authentication.SignIn(options, identity);
于 2016-10-31T21:22:58.933 に答える